Skip to content

プリザンターの MCP ​

第9版作成 最終更新 (日本時間)
対応バージョンPleasanter 1.5.2.0 以降確認バージョン1.5.2.01.5.8.1

プリザンターには、AI クライアント(Claude Desktop、Visual Studio Code など)からレコードやビューを操作できる MCP(Model Context Protocol)サーバがあります(1.5.2.0 で実装)。 MCP は標準 API をそのまま全部公開し直したものではなく、AI が使いやすい範囲を選んだ操作面です。入口のプロトコルは異なりますが、内部ではコントローラより内側の共通処理(モデル生成・権限判定・検索条件の適用・保存)に合流するため、API と同じアクセス権と入力規則が適用されます。

対象バージョン

アーキテクチャの説明は 1.5.2.0、ツール一覧と内部の流れは 1.5.8.1 を対象にしています。ツールは今後追加・変更される可能性があるため、利用中の環境では接続先が返す tools/list の結果を正としてください。

MCP サーバの仕組み ​

MCP の機能カテゴリ ​

MCP は Anthropic 社が策定したオープンプロトコルで、AI アプリケーションと外部ツール・データソースを標準的な方法で接続します。

図を読み込み中…

MCP サーバが提供できる機能は 3 種類あり、プリザンターでは主に Tools が実装されています。

カテゴリ説明プリザンターでの利用(1.5.2.0 時点)
Tools(ツール)AI が呼び出せるアクション(関数)レコード取得・更新、ビュー操作など
Resources(リソース)コンテキスト情報としてのデータ未使用
Prompts(プロンプト)テンプレート化されたワークフロー未使用

有効化 ​

McpServer.json の Enabled を true にしてサービスを再起動すると、/mcp エンドポイントが有効になります。

json
{
    "Enabled": true
}

ASP.NET Core への統合には ModelContextProtocol.AspNetCore NuGet パッケージが使われています。既存の API が MapControllerRoute によるコントローラベースのルーティングであるのに対し、MCP は MapMcp("/mcp") でエンドポイントを追加する形です。

標準 API との違い ​

観点標準 APIMCP サーバ
プロトコルHTTP(独自 JSON)JSON-RPC 2.0 over Streamable HTTP
エンドポイント操作ごとに個別 URL(すべて POST)/mcp の単一エンドポイント(method で操作を指定)
認証リクエストボディ内の ApiKeyHTTP ヘッダ X-API-Key(または Authorization: Bearer)
セッションステートレスMcp-Session-Id ヘッダで管理
ストリーミング非対応SSE で対応可能
エラー形式独自の StatusCodeJSON-RPC エラーコード
ログSysLog専用の MCP ログ(/mcplogs)

API キーはどちらも同じ仕組み(Users テーブルの ApiKey)で、管理画面で発行した API キーがどちらでも使えます。MCP ではツールの引数(arguments)に認証情報を含めず、トランスポート層(ヘッダ)で認証します。MCP は X-API-Key ヘッダを先に見て、無ければ Authorization: Bearer <API キー> を使います(McpApiKeyHelper.cs)。HTTP ヘッダ名は大文字・小文字を区別しないので、X-Api-Key と書いても同じです。

text
# 標準 API のリクエスト
POST /api/items/12345/Get HTTP/1.1
Content-Type: application/json

{"ApiKey":"xxx-xxx","ApiVersion":1.1}

# MCP サーバのリクエスト
POST /mcp HTTP/1.1
Content-Type: application/json
X-API-Key: xxx-xxx

{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"GetItems","arguments":{"siteId":12345}}}

ライフサイクル ​

API の各リクエストが独立しているのに対し、MCP ではセッションが維持され、クライアントは利用可能なツール一覧を取得してから呼び出します。

図を読み込み中…

フェーズ内容
initializeクライアントとサーバがプロトコルバージョンと対応機能を交換
initialized初期化完了の通知
tools/listサーバが提供するツールの一覧を返す
tools/call指定ツールを実行し結果を返す
shutdownセッション終了

エラー ​

MCP のエラーは JSON-RPC 2.0 の形式です。API 独自のステータス(429: API 上限超過など)は、JSON-RPC エラーの data フィールドにマッピングされます。

JSON-RPC エラーコード意味
-32700パースエラー
-32600不正なリクエスト
-32601メソッド未検出
-32602不正なパラメータ
-32603内部エラー

MCP ログ ​

MCP サーバには専用のログ管理機能があり、http(s)://{サーバ名}/{パス}/mcplogs でアクセスできます。ログはデータベースに記録され、CSV 出力や不要ログの削除にも対応しています。

項目説明
ユーザーAPI キーに紐づくユーザー
API キー使用された API キー
経過時間リクエスト処理にかかった時間
リクエスト内容JSON-RPC リクエスト本文
レスポンス内容JSON-RPC レスポンス本文

MCP ログはレコード履歴ではない

MCP ログは「どのツールをどう呼んだか」を追うためのもので、レコードの過去版を持つ「履歴」とは目的も保持データも異なります。

ツール一覧と標準 API との対応 ​

確認したソースで [McpServerTool] が付いているツールは 20 個です(MCP/Tools 配下の ItemsTool.cs・SitesTool.cs・UsersTool.cs・ViewsTool.cs・OutgoingMailsTool.cs)。エンドポイントの {id} は操作によってサイト ID またはレコード ID です。URL はルート配置なら /api/...、サブディレクトリ配置なら /fs/api/... のように変わります。

バージョンによる差

以下は 1.5.8.1 のソースで確認したツールの一覧です(1.5.2.0 では 16 個でした)。CreateItem・CopyItem・Reference・CreateUpdateItemJson・SendMail という名前のツールは 1.5.8.1 には無く、作成は AddItem、JSON 生成は CreateItemJson、メール送信は SendEmail です。

レコードとサイト ​

MCP ツール目的対応する標準 API差分・注意点
GetItemsサイトのレコード一覧を取得POST /api/items/{siteId}/getviewJson と offset を受け取る。1 回の取得は 200 件
GetItem1 レコードを取得POST /api/items/{recordId}/get現行版のレコードを取得。履歴取得ではない
AddItemレコードを作成POST /api/items/{siteId}/create内部で CreateByApi を呼ぶ。添付ファイルは AttachmentsHash で渡す
UpdateItemレコードを更新POST /api/items/{recordId}/update更新可能な項目と権限の制約を受ける
DeleteItemレコードを削除POST /api/items/{recordId}/delete破壊的操作。ReadOnlyMode では利用できない
CreateItemJson作成・更新用 JSON を組み立て該当なしデータを書き込まず JSON を生成する支援ツール。日本語の項目名・分類の表示値を内部コードに変換する
GetSiteサイト情報(サイト設定)を取得POST /api/items/{siteId}/getsite に近い項目定義・選択肢・権限情報などを返す。レコードの Get とは別物
GetSiteIdByTitleサイト名から ID を検索1 対 1 の API なしAI が名前で指定するためのヘルパー
GetSiteTemplatesサイトテンプレートの一覧を取得1 対 1 の API なし定義テンプレートとユーザーテンプレートを返す
AddSiteByTemplateテンプレートからサイトを作成1 対 1 の API なしGetSiteTemplates の ID を指定する。ReadOnlyMode では利用できない

ユーザーとメール ​

MCP ツール目的対応する標準 API差分・注意点
GetUsersユーザー一覧を取得POST /api/users/get取得可能な範囲は実行ユーザーの権限に従う
GetUserIdByName名前からユーザー ID を検索1 対 1 の API なしGetUsers と検索条件の組み立てをツール化
SendEmailレコードにひも付くメールを送信POST /api/items/{recordId}/OutgoingMails/Send内部で OutgoingMailUtilities.SendByApi を呼ぶ。メール設定と送信権限が必要

ビュー ​

API にはビューの管理機能がなく、ビューの作成・更新は Web UI でしかできませんでした。MCP ではビューの CRUD がツールとして提供されています。

MCP ツール目的標準 API との関係差分・注意点
GetViewビュー定義を取得1 対 1 の公開 API なしMCP 固有の管理操作
AddViewビューを追加サイト設定の保存処理を利用サイト設定を変更
UpdateViewビューを更新サイト設定の保存処理を利用サイト設定を変更
CopyViewビューを複製取得と追加を組み合わせる元のビュー ID と複製後の ID は異なる
DeleteViewビューを削除サイト設定の保存処理を利用破壊的操作
GetViewIdByViewNameビュー名から ID を検索該当なしAI 向けの名前解決
CreateViewJson絞り込み・ソート用 JSON を生成該当なし登録せず、GetItems に渡す一時的な条件にも利用可能

標準 API にあって MCP にはないもの ​

機能MCP での扱い実務上の影響
履歴一覧・特定履歴の取得非対応監査、差分比較、変更者の追跡には標準 API が必要
一括削除専用ツールなしDeleteItem の繰り返しは誤操作時の影響が大きい
インポート専用ツールなしCSV などの大量投入は標準 API 向き
エクスポート専用ツールなし帳票やバックアップ用途は標準 API 向き
Upsert専用ツールなし外部キーによる同期処理は標準 API の方が組み立てやすい
添付ファイル単体の操作専用ツールなしバイナリの取得・送信は別経路を用意
管理系 API 全般限定的MCP をシステム管理 API の代わりにしない

AI 向けの設計 ​

名前から ID を解決するツール ​

API では開発者がサイト ID やユーザー ID を事前に把握していますが、AI は「営業管理のサイト」「田中さん」のように名前で指定します。GetSiteIdByTitle・GetUserIdByName・GetViewIdByViewName は、表示名から後続ツールが要求する ID を得る定型処理をまとめたものです。

名前は一意とは限らない

候補が複数返り得る環境では、AI に最初の 1 件を無条件で選ばせず、サイト階層、ログイン ID、メールアドレスなどの追加情報で対象を確認させます。

項目の定義は GetSite とリソースで確認する ​

「担当者を田中さんに変更して」と依頼されたとき、AI は次を知らなければ書き込みデータを作れません。

  • 「担当者」の物理名
  • 値が表示名なのか、ユーザー ID なのか
  • 単一選択か複数選択か
  • 参照先のサイトや選択肢
  • 読み取り専用の項目ではないか

1.5.8.1 には、このための専用ツール(Reference)はありません。サイトごとの定義は GetSite が返すサイト設定から読み取り、JSON の書き方は MCP のリソースとして公開されている仕様(resource://pleasanter/specs/item-fields、site-settings、choices-pattern、view-json、paging、tool-capabilities)で確認します(ItemFieldsResource.cs)。リソースはどのサイトでも同じ内容の説明文で、サイト固有の項目定義は含みません。

典型的な更新の流れは次のとおりです。CreateItemJson の時点ではまだ保存されていません。

図を読み込み中…

WARNING

GetSite の結果は、実行ユーザーにその項目を更新する権限があることまでは保証しません。実際の読み書きでは、サイト・レコード・項目それぞれの権限判定が適用されます。

JSON 生成ツール ​

CreateItemJson と CreateViewJson は、AI が複雑な JSON 構造を正しく組み立てるのを支援するツールで、それ自体はデータを保存しません。

  • CreateViewJson は自然言語の条件(例: 「ステータスが進行中のレコードを更新日の新しい順」)から View JSON を生成し、GetItems や GetUsers の viewJson に渡します。生成例: {"ColumnFilterHash":{"Status":"200"},"ColumnSorterHash":{"UpdatedTime":"desc"}}
  • CreateItemJson は、キーに項目名(日本語の表示名も可)、値に設定する値を受け取り、分類項目の表示値を内部コードに変換して AddItem / UpdateItem 用の JSON を返します(ItemsTool.cs)。JSON を生成できても、必須入力・形式・重複・読み取り専用項目・状態遷移・アクセス権は AddItem / UpdateItem の共通処理で改めて判定されます

CreateViewJson で作った条件は一時的な検索条件として GetItems に渡し、永続化したい場合だけ AddView や UpdateView を呼ぶ、という 2 段階に分けると誤変更を防ぎやすくなります。

このほか、MCP のプロンプトとして search-records・save-records・assign-user-to-record・send-email などの定型手順も公開されています(WorkflowPrompts.cs)。

ツールの定義 ​

MCP ツールは ModelContextProtocol NuGet パッケージの規約に従い、C# の属性でメタデータを定義します。この定義からツールのスキーマ(inputSchema)が自動生成され、tools/list で返されます。1.5.8.1 の GetItems の定義は次の形です(ItemsTool.cs、処理本体は省略)。

csharp
[McpServerTool(Name = "GetItems")]
[Description(@"指定サイトのレコード一覧を取得します。...")]
public static async Task<CallToolResult> GetItems(
    [Description(@"取得対象のサイト ID。")]
        long siteId,
    [Description(@"検索条件の View JSON 文字列。CreateViewJson で作成。...")]
        string viewJson = "",
    [Description(@"取得開始位置。PageSize 200 のため、2ページ目は 200、3ページ目は 400 を指定。")]
        int offset = 0)

取得件数を引数で変えることはできず、ページ送りは offset で行います。

内部の流れ ​

MCP は API へ HTTP でループバックしない ​

図を読み込み中…

MCP から /api/... へ HTTP リクエストを再送信する構造ではありません。MCP ツールは C# のメソッドとして引数を受け取り、コントローラより内側にあるモデル生成、View の適用、権限判定、データ取得・保存の層をプロセス内で呼び出します。API の ItemsController.Get() も MCP の GetItems も、最終的には同じ GetByApi() を呼び出します。

境界MCP 側の役割共通処理側の役割
プロトコルtools/call を受ける関与しない
引数AI 向けの名前と説明を公開する型と業務ルールを検証する
検索条件JSON 生成を支援するView を解釈して SQL を組み立てる
認証API キーから実行コンテキストへ橋渡しするテナントとユーザーを判定する
認可エラーを MCP の結果へ戻すサイト・レコード・項目権限を判定する
応答AI が読める形へ格納する取得データを生成する

この分担により、MCP だけが権限チェックを迂回する経路にならず、API と MCP で入力規則や更新後の動作がばらばらになるのを防いでいます。

参照系ツール ​

GetItems の引数と API 側の概念は次のように対応します。

MCP から受け取る情報API 側の概念内部での役割
サイト IDURL の {siteId}対象サイトとテーブル種別を決める
ビュー JSONリクエストの Viewフィルター、ソート、列指定を組み立てる
ページ条件Offset、PageSize など取得範囲を制限する
API キーに対応する認証情報ApiKey またはセッション実行ユーザーとテナントを確定する

処理はおおむね次の順です。GetItems を呼べたことは、そのサイトの全データを読めることを意味しません。

  1. MCP の認証情報から実行コンテキストを確定する
  2. サイト ID からサイト設定とテーブル種別を読み込む
  3. ビュー JSON をプリザンターの View として解釈する
  4. サイト、レコード、項目の読み取り権限を確認する
  5. 許可された列と行だけを取得する
  6. API と同系統のデータを MCP の結果へ格納する

GetItem はレコード ID から対象レコードとサイトを特定し、閲覧権限を確認してから Issue または Result のモデルを生成します。

GetItem で履歴は取得できない

GetItem が返すのは指定したレコードの現行版です。履歴番号を付けて呼ぶ、GetItems の View で履歴テーブルを指定する、といった使い方はできず、履歴一覧・特定履歴を取得する専用ツールもありません。「変更履歴を時系列で並べて」「履歴 3 と現在の差分を見せて」「誰が値を変更したか追跡して」「過去の添付ファイルを取得して」といった依頼は MCP だけでは完結しないため、履歴用の標準 API を呼ぶツールを追加するか、AI アプリケーション側で標準 API と併用します。

更新系ツール ​

更新系でも、AI が作った値をそのまま SQL に流すわけではなく、モデル・入力検証・権限判定・プロセス・保存処理を通ります。

図を読み込み中…

ツール内部の流れ
AddItemサイト ID から Issues / Results を判定 → サイト設定で新規モデルを用意 → JSON の物理名と値を適用 → 作成権限・項目権限・必須項目・値形式を検証 → 採番・計算・プロセスなどを反映して保存 → 新しいレコード ID を返す
UpdateItemレコード ID から現在のモデルとサイト設定を読み込み、渡された項目だけを適用 → 更新権限・項目権限・入力・状態・競合を検証 → 保存
DeleteItem削除 API と同系統。対象の存在、削除権限、サイト設定、関連処理を確認してから削除
SendEmail単独の SMTP クライアントではなく、対象レコードを起点にメール送信 API と同系統の処理へつながる。対象レコード・送信権限・宛先・メール設定の条件を受ける
ビュー系対象サイトとビューを解決 → サイト管理権限と定義を検証 → サイト設定を保存

UpdateItem を AI に許可するときは、ツールがあるかだけでなく、対象サイトの更新権限、対象レコードの更新可否、指定項目が読み取り専用でないか、プロセスや状況による制限、別ユーザーによる同時更新を確認します。

エラーの発生源 ​

層例確認すること
MCP プロトコルツール名がない、引数の型が違うtools/list のスキーマ
MCP アダプターJSON を解釈できない、必須引数がないツールへ渡した引数
共通検証権限不足、必須項目不足、値形式違反ユーザー、サイト設定、項目定義
保存競合、制約違反、関連処理の失敗更新時刻、プロセス、ログ
外部連携メール送信失敗メール設定と外部サービス

MCP と API の結果に差が出たときは、すぐにデータ取得ロジックの違いと判断せず、まず既定値、ページサイズ、応答整形、実行ユーザーを確認します。同じ実行ユーザーとデータで標準 API を試すと、アダプターの問題か共通処理の問題かを切り分けやすくなります。

クライアントからの接続 ​

Claude Desktop ​

Claude Desktop などの AI エージェントは通常 stdio トランスポートで MCP サーバと通信しますが、プリザンターの MCP サーバは Streamable HTTP です。この差を mcp-remote プロキシで埋めます。

図を読み込み中…

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

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"
            }
        }
    }
}
設定項目説明
commandmcp-remote の実行コマンド(Node.js 18 以上)
URL 引数プリザンターの MCP エンドポイント URL
--headerX-API-Key ヘッダで API キーを送信
--allow-httpHTTP 接続を許可(開発環境向け)
NODE_TLS_REJECT_UNAUTHORIZED自己署名証明書対応(本番では非推奨)

WARNING

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

VS Code ​

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

安全に公開する ​

tools/list にツールが表示されても、任意のデータを読み書きできるわけではありません。MCP の実行ユーザーには通常と同じ権限判定が適用されます。McpServer.json の ReadOnlyMode を有効にすると、読み取り用途に限定できます。1.5.8.1 では、ReadOnlyMode で使えるのは GetItem・GetItems・CreateItemJson・GetSite・GetSiteIdByTitle・GetSiteTemplates・GetUserIdByName・GetUsers・CreateViewJson・GetView・GetViewIdByViewName の 11 個で、それ以外のツールはエラーを返します(ToolPermission.cs)。

json
{
  "Enabled": true,
  "ReadOnlyMode": true
}

段階的に開放する手順の例です。

  1. MCP 専用の低権限ユーザーを用意する
  2. ReadOnlyMode: true で参照系ツールの動作を確認する
  3. 書き込み可能なサイトと項目をアクセス制御で限定する
  4. 作成・更新から始め、削除・メール・ビュー管理は別に判断する
  5. 破壊的操作の前に MCP クライアント側で対象と変更内容を表示する
  6. MCP の呼び出しログとレコード履歴の両方を監視する

そのほかの観点は次のとおりです。

観点対策
API キー管理定期的なローテーション推奨
TLS 通信本番環境では CA 証明書を使用
レート制限McpServer.json の RateLimit(FixedWindow・SlidingWindow・TokenBucket・Concurrency)で設定可能。既定はすべて無効
ログ監査/mcplogs で全リクエストを記録
IP 制限Security.json の AllowIpAddresses は MVC のフィルタ(CheckApiContextAttributes など)で判定されます。1.5.8.1 のソースでは MCP のミドルウェア側に同じ判定は見当たらず、/mcp に適用されるかは確認できていないため、リバースプロキシやファイアウォールでも制限する
SendEmail外部への影響が大きいため、専用ユーザー、許可するサイト、宛先の範囲、確認画面、ログの保存を先に設計する
DeleteItem一括削除の代わりに 1 レコード単位で扱い、件数上限や人の承認を組み合わせる

ブラウザで /mcp を開くと JSON のエラーが出る ​

/mcp をブラウザのアドレスバーで開くと、プリザンターのエラー画面ではなく、JSON-RPC のエラー({"jsonrpc":"2.0","error":{...}} の形)がそのまま表示されます。

  • MCP の仕様(Streamable HTTP トランスポート)では、クライアントは GET に Accept: text/event-stream を付けることになっており、ブラウザからの直接アクセスは想定されていません。ブラウザの通常の GET はこれを満たさないため、SDK がエラーを返します。
  • 1.5.8.1 は ModelContextProtocol.AspNetCore 1.4.1 を使い、WithHttpTransport() をオプションなしで登録して MapMcp("/mcp") しています(Implem.Pleasanter.csproj#L73、Startup.cs#L368-L376、Startup.cs#L795-L798)。
  • プリザンターの UseStatusCodePages は 400・405 などを /errors/badrequest などのエラー画面へリダイレクトしますが、これは応答の本文が空のときだけ働きます。SDK は本文に JSON-RPC のエラーを書いてから返すため、リダイレクトされません(Startup.cs#L528-L572)。
  • McpContextMiddleware が解析・ログ記録するのは POST だけで、GET はそのまま SDK に渡ります(McpContextMiddleware.cs#L27-L75)。

エラーの文言とステータスコードは SDK のバージョンで変わります(SDK 1.0.0 で調べたときは、406 と Not Acceptable: Client must accept text/event-stream でした)。MCP クライアントからの接続には影響しない表示上の問題です。ブラウザ向けに分かりやすい画面を返す方法は MCP エンドポイントのブラウザアクセス対策 を参照してください。

MCP と標準 API の使い分け ​

MCP が向く処理標準 API が向く処理
「営業管理サイトの未完了案件を要約して」のような対話的な参照処理手順と入出力が決まっている定期バッチ
サイト名やユーザー名から対象を探す操作大量データの入出力、一括更新、一括削除、インポート・エクスポート
GetSite で項目定義を確認しながら行う少量の作成・更新Upsert を使った他システムとの同期
会話で条件を調整しながらビューを作る操作履歴の取得や監査データの収集、添付ファイルを含む連携
再実行・冪等性・件数管理を厳密に実装する処理、スクリプトからの呼び出し

必要な操作が MCP にない場合は、AI に無理な代替手順を実行させず、標準 API に切り替える境界を決めておきます。

別バージョンで確認するときのチェックポイント ​

  1. MCP クライアントから tools/list を取得する
  2. ツール名だけでなく description と inputSchema を保存する
  3. 同じ対象を操作する標準 API のリクエストとレスポンスを比較する
  4. 現行レコード、履歴、サイト定義、MCP ログを混同していないか確認する
  5. ReadOnlyMode と権限の有無で結果がどう変わるか試す

関連ページ ​

変更履歴

第9版VehicleVision.PleasanterTools を専用セクションにし、トップページに新着リリースを表示
第8版記事の確認版を繰り返す表現を整理する
第7版CodeDefiner のデータベース作成・更新とパラメータの引き継ぎ、画面でのパラメータ管理、MCP エンドポイントのブラウザアクセスの解説と、関連する改修・設計メモを追加
第6版「外部連携・AI」「構築・運用」「内部実装を読む」に対応バージョンを表示
第5版Entra ID の SAML SSO にソースで確認した ACS URL・署名アルゴリズム・反映方法を反映
第4版「外部連携・AI」を 1.5.8.1 のソースで検証して修正
第3版元記事への言及を整理し、必要なコードをページに収録。検索機能に一覧の検索と絞り込みを追加
第2版記事のファイル名に並び順の番号を付け、元記事リンクを frontmatter の sources に移行
第1版「外部連携・AI」セクションの記事を追加