0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

プリザンターのMCPサーバの実装を詳しくみてみる[後編:ツール実装編]

0
Posted at

はじめに

前回(前編)では、プリザンターの MCP サーバと既存 API のアーキテクチャを比較しました。今回は、MCP サーバに実装されているツールの具体的な設計と、クライアントとの連携の仕組みを詳しく見ていきます。

テーマ
前編 アーキテクチャ編 — MCP プロトコルの概要と既存 API との設計比較
後編(本記事) ツール実装編 — MCP ツールの設計とクライアント連携の仕組み

バージョン 1.5.2.0 を対象にしています

MCP ツールの全体像

プリザンターの MCP サーバでは、16 個のツールが提供されています。これらは機能カテゴリごとに整理されており、AI エージェントが tools/list で一覧を取得してから呼び出します。

ツール一覧

カテゴリ ツール名 機能 API 対応
レコード操作 GetItems レコード一覧取得 POST /api/items/{siteId}/Get
レコード操作 GetItem レコード詳細取得 POST /api/items/{id}/Get
レコード操作 UpdateItem レコード更新 POST /api/items/{id}/Update
レコード操作 CreateUpdateItemJson 更新用 JSON 生成 (該当なし — MCP 固有)
サイト操作 GetSite サイト設定取得 POST /api/items/{siteId}/Get
サイト操作 GetSiteIdByTitle サイト名から ID 検索 (該当なし — MCP 固有)
ユーザー操作 GetUsers ユーザー一覧取得 POST /api/users/Get
ユーザー操作 GetUserIdByName ユーザー名から ID 検索 (該当なし — MCP 固有)
ビュー操作 GetView ビュー設定取得 (該当なし — MCP 固有)
ビュー操作 AddView ビュー追加 (該当なし — MCP 固有)
ビュー操作 UpdateView ビュー更新 (該当なし — MCP 固有)
ビュー操作 CopyView ビューコピー (該当なし — MCP 固有)
ビュー操作 DeleteView ビュー削除 (該当なし — MCP 固有)
ビュー操作 GetViewIdByViewName ビュー名から ID 検索 (該当なし — MCP 固有)
ビュー操作 CreateViewJson 検索用 View JSON 生成 (該当なし — MCP 固有)
メール SendMail メール送信 POST /api/items/{id}/SendMail

API との対応関係

上の表からわかるように、MCP ツールの多くは API にはないオリジナルの機能です。特に注目すべきは、AI が自律的に操作できるようにするためのヘルパーツールが追加されていることです。

AI エージェントのための設計思想

なぜ「JSON 生成ツール」が必要なのか

API を人間が使う場合、開発者はドキュメントを読んで JSON リクエストを組み立てます。しかし、AI エージェントがプリザンターの複雑な JSON 構造を正しく構築するのは難しい場合があります。

そこで MCP サーバには CreateUpdateItemJsonCreateViewJson というJSON 生成専用ツールが用意されています。

このように、ツールを 2 段階で呼び出すことで、AI エージェントは複雑な JSON 構造を意識せずにレコード操作を実行できます。

名前から ID への解決ツール

API ではサイト ID やユーザー ID を事前に知っている必要がありますが、AI エージェントは「営業管理のサイト」や「田中さん」のように名前で指定します。

GetSiteIdByTitleGetUserIdByName はこの名前→ID の解決を担うツールです。

API ではこのようなヘルパーは不要でした(開発者が事前に ID を把握しているため)。MCP ツール設計は、人間ではなく AI が操作することを前提に最適化されています。

ツールの実装パターン

ASP.NET Core での MCP ツール定義

プリザンターの MCP ツールは、ModelContextProtocol NuGet パッケージの規約に従い、C# の属性(Attribute)でツールメタデータを定義します。

[McpServerToolType]
public class PleasanterMcpTools
{
    [McpServerTool, Description("指定サイトのレコード一覧を取得します")]
    public static string GetItems(
        [Description("サイトID")] long siteId,
        [Description("検索条件のView JSON(省略可)")] string viewJson = null,
        [Description("取得件数(デフォルト200)")] int pageSize = 200)
    {
        // 内部で既存の GetByApi ロジックを呼び出す
    }
}

この定義から、MCP サーバは自動的にツールのスキーマを生成します。AI クライアントが tools/list を呼び出すと、以下のような情報が返されます。

{
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
        "tools": [
            {
                "name": "GetItems",
                "description": "指定サイトのレコード一覧を取得します",
                "inputSchema": {
                    "type": "object",
                    "properties": {
                        "siteId": {
                            "type": "integer",
                            "description": "サイトID"
                        },
                        "viewJson": {
                            "type": "string",
                            "description": "検索条件のView JSON(省略可)"
                        },
                        "pageSize": {
                            "type": "integer",
                            "description": "取得件数(デフォルト200)"
                        }
                    },
                    "required": ["siteId"]
                }
            }
        ]
    }
}

API コントローラとの対比

既存 API では、1 つの操作=1 つのコントローラアクションです。

Implem.Pleasanter/Controllers/Api/ItemsController.cs
// API: URL パスとHTTPメソッドで操作を特定
[HttpPost("{id}/Get")]
public ContentResult Get(long id) { ... }

[HttpPost("{id}/Create")]
public ContentResult Create(long id) { ... }

[HttpPost("{id}/Update")]
public ContentResult Update(long id) { ... }

MCP ツールでは、1 つの操作=1 つの [McpServerTool] メソッドです。URL パスは不要で、ツール名がそのまま識別子になります。

// MCP: ツール名で操作を特定
[McpServerTool, Description("レコード一覧を取得します")]
public static string GetItems(long siteId, ...) { ... }

[McpServerTool, Description("レコードを更新します")]
public static string UpdateItem(long itemId, ...) { ... }

内部ロジックの再利用

重要なポイントは、MCP ツールの内部実装が既存の API ロジックを再利用していることです。

API の ItemsController.Get() も MCP の GetItems ツールも、最終的には同じ GetByApi() メソッドを呼び出してデータを取得します。つまり、権限チェック、フィルタリング、ページネーションなどのビジネスロジックはすべて共有されています。

ビュー操作ツール — API にはない機能

ビュー操作の背景

API にはビューの管理機能がありません。ビューの作成・更新は Web UI でしかできませんでした。MCP サーバでは、ビューの CRUD 操作がツールとして実装されており、AI エージェントが自律的にビューを管理できます。

CreateViewJson ツールの役割

CreateViewJson は、検索条件やソート順を含む View JSON 文字列を生成するヘルパーツールです。生成された JSON は GetItemsGetUsersviewJson パラメータに渡して使います。

AI: 「ステータスが"進行中"のレコードを更新日の新しい順で取得して」

→ tools/call: CreateViewJson
  → 生成結果: {"ColumnFilterHash":{"Status":"200"},"ColumnSorterHash":{"UpdatedTime":"desc"}}

→ tools/call: GetItems
  → viewJson に生成結果を渡す
  → フィルタ・ソート済みのレコード一覧が返る

API では開発者が View オブジェクトの JSON を手動で構築していましたが、MCP では AI エージェントが自然言語の指示からツールを連携して条件を組み立てます。

クライアント連携の仕組み

mcp-remote プロキシ

AI エージェント(Claude Desktop など)は通常 stdio(標準入出力)トランスポートで MCP サーバと通信します。一方、プリザンターの MCP サーバは Streamable HTTP トランスポートです。

この差を埋めるのが mcp-remote プロキシです。

Claude Desktop の設定

Claude Desktop から接続する場合、.mcpb 拡張ファイルをインストールするか、設定ファイルを直接編集します。

claude_desktop_config.json
{
    "mcpServers": {
        "pleasanter": {
            "command": "node",
            "args": [
                "node_modules/mcp-remote/dist/proxy.js",
                "https://pleasanter.example.com/mcp",
                "--header",
                "X-Api-Key:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
                "--allow-http"
            ],
            "env": {
                "NODE_TLS_REJECT_UNAUTHORIZED": "0"
            }
        }
    }
}
設定項目 説明
command mcp-remote の実行コマンド(Node.js 18 以上)
URL 引数 プリザンターの MCP エンドポイント URL
--header X-Api-Key ヘッダで API キーを送信
--allow-http HTTP 接続を許可(開発環境向け)
NODE_TLS_REJECT_UNAUTHORIZED 自己署名証明書対応(本番では非推奨)

NODE_TLS_REJECT_UNAUTHORIZED=0 は TLS 証明書の検証を無効化するため、中間者攻撃のリスクがあります。本番環境では信頼された CA 証明書を使用してください。

VS Code からの接続

VS Code の場合は、MCP 拡張機能の設定でエンドポイント URL と API キーを入力するだけで接続できます。VS Code は Streamable HTTP トランスポートを直接サポートしているため、mcp-remote プロキシは不要です。

API と MCP のユースケース比較

どちらを使うべきかは、用途によって異なります。

ユースケース API MCP サーバ
定型的なバッチ処理 ✅ 最適 △ オーバーヘッド大
外部システム連携 ✅ 最適 △ MCP 対応が必要
AI エージェント連携 △ JSON 構築が複雑 ✅ 最適
対話的なデータ探索 △ 複数リクエストが必要 ✅ ツール連携で自律操作
ビュー管理の自動化 ✗ 非対応 ✅ 専用ツールあり
スクリプトからの呼び出し ✅ curl/httpClient で簡単 △ MCP クライアントが必要

API が適するケース

  • 定型処理の自動化:決まったサイト ID・フィルタ条件でデータを取得・更新するバッチ処理
  • 既存システムとの統合:ERP や CRM など、HTTP を前提とした外部システムとの連携
  • スクリプト連携:PowerShell や Python から直接 API を呼び出す場合

MCP サーバが適するケース

  • AI アシスタントとの連携:Claude Desktop や VS Code から自然言語でプリザンターを操作
  • 探索的なデータ分析:「今月の未完了タスクを担当者別に集計して」のような複雑な操作
  • ビュー管理の効率化:ビューの作成・コピー・削除を AI に任せる
  • レポート生成:AI にデータを取得させ、分析結果をレポートにまとめる

セキュリティの考慮事項

共通の認証基盤

MCP サーバと API は、同じ API キーの仕組みを使用しています。プリザンターの管理画面で発行した API キーが、どちらのインターフェースでも使えます。

MCP 固有のセキュリティ

観点 対策
API キー管理 定期的なローテーション推奨
TLS 通信 本番環境では CA 証明書を使用
レート制限 McpServer.json で設定可能
ログ監査 /mcplogs で全リクエストを記録
IP 制限 既存の AllowIpAddresses 設定が適用される

まとめ

前後編を通じて、プリザンター 1.5.2.0 の MCP サーバを実装面から解説しました。

前編の振り返り

  • MCP は JSON-RPC 2.0 ベースのプロトコルで、/mcp の単一エンドポイントで動作する
  • API がコントローラベースのルーティングであるのに対し、MCP は MapMcp でエンドポイントを追加
  • 認証方式がボディ内 ApiKey からヘッダ X-Api-Key に変わった
  • エラー形式が独自 StatusCode から JSON-RPC エラーコードに統一された

後編のまとめ

  • 16 個のツールが提供され、うち半数以上は API にないオリジナル機能
  • CreateUpdateItemJson / CreateViewJson など、AI エージェントの自律操作を支援するヘルパーツールが設計のポイント
  • 内部ロジックは既存の GetByApi / UpdateByApi を再利用しており、二重実装ではない
  • mcp-remote プロキシにより、stdio ベースの AI クライアントと HTTP ベースのサーバを橋渡し

MCP サーバは API を置き換えるものではなく、AI エージェント向けの新しいアクセス手段を追加するものです。既存の API は引き続きバッチ処理やシステム連携で活用し、MCP は AI との対話的な操作に使い分けるのが効果的です。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?