メインコンテンツまでスキップ

API連携ガイド

外部システムからPlantPulse AIのMCP及びAPIを直接呼び出す方法です。

無くなったアドレスを叩かないでください

旧独立サービス MCP Server(:50000) · Ontology(:8888) はアーカイブされ、LightRAG を 直接開いていた :7114 もありません。 ツールは MCPゲートウェイ 一つのアドレスに集まります → MCPツールマップ


MCP クライアントはゲートウェイ一つのアドレスで​

外部 MCP クライアント(他のエージェント · デスクトップアプリなど)は https://<호스트>/mcp/gateway/ 一つで接続します(Streamable HTTP)。 プラットフォーム統合MCP · 時系列インサイト · RAG · ドキュメント理解 · ビジョン · 工学計算 · デジタルスレッド · 運用者が接続した外部サーバーのツールがこのアドレスに集まります。

やること場所
キーを受け取るAI管理コンソール › MCP ゲートウェイ › クライアント API キー で キー発行 — キー(ppgw_…)は発行直後に 一度だけ 表示されます。キーに 範囲(設備 · サイト · プロジェクト · 顧客 PO · 協力会社)と 等級 を与えます — 範囲のないキーは外部サーバーのツールだけを呼び出せます
見せるツールを決める同じメニューの 権限 — 新しいキーは 何も許可されていない状態 で始まります。サーバーごとに «すべてのツール» または一部のツールを許可します
呼び出すX-API-Key: ppgw_… または Authorization: Bearer ppgw_…
呼び出しを見るモニタリング › 呼び出し記録・指標 — キーごとに呼び出しが残ります
  • キーがないか誤っていれば 401、1分間に20回を超えて誤ったクライアントはその1分間 429 です。
  • このパスはゲートウェイの MCP(/mcp/)だけを渡します。ゲートウェイ管理 REST(/api/v1)は外部に開かれません。
  • 末尾スラッシュのない /mcp/gateway は /mcp/gateway/ へ転送します(308)。
  • 画面 · 権限 · キーの廃棄は → AI管理コンソール — MCP ゲートウェイ

その他のエンドポイント​

サービスURLプロトコル認証
MCPゲートウェイhttps://<호스트>/mcp/gateway/MCP (Streamable HTTP)ゲートウェイキー ppgw_… — 上記
コパイロット公開APIhttps://<호스트>/api/v1/…RESTX-API-Key → 下記
LiteLLM(モデル)http://<server>:4000OpenAI互換マスターキー
統合MCP(プラットフォーム)<platform>/api/v5/mcpMCP (JSON-RPC 2.0)api_key — Authorization: Bearer または X-API-Key

サービス直結 — 運用者 · システム連携用​

社内MCPサーバーはゲートウェイを経由せず 直接 も開いています。ただし認証が インストール共通のインバウンドキー(PI_INBOUND_API_KEY)一つなので そのキーを持つ側は 全権 であり、呼び出し元ごとのツール権限も呼び出し記録もありません。 運用者スクリプト · プラットフォーム CEP のような システム連携 にだけ使い、顧客の MCP クライアントには ゲートウェイ を渡してください。

サービス直結アドレス認証
時系列インサイトhttp://<server>:8970/mcp/ · https://<호스트>/mcp/timeseries/インバウンドキー
RAGゲートウェイhttp://<server>:7115/mcp/ · https://<호스트>/mcp/rag/インバウンドキー
ドキュメント理解https://<호스트>/mcp/parser/(ホストポート 7120 は 未発行)インバウンドキー
ビジョンhttps://<호스트>/mcp/vision/(ホストポート 7130 は 未発行)インバウンドキー

デジタルスレッド · 工学計算 · プラットフォーム統合MCP を一つのアドレスで受ける道はゲートウェイだけです。

基本ホストのパスでも開いています​

サブドメインやポートを別途開かなくても、プロキシが 基本ホスト(チャットと同じアドレス)のパスで 次を渡してくれます。

パス渡される先
https://<호스트>/mcp/gateway/MCPゲートウェイのMCP — 外部MCPクライアントはこれ
https://<호스트>/llm/LiteLLM — OpenAI SDKの base_url は https://<호스트>/llm/v1
https://<호스트>/mcp/rag/RAGゲートウェイのMCP
https://<호스트>/mcp/timeseries/時系列インサイトのMCP
https://<호스트>/mcp/parser/ドキュメント理解のMCP
https://<호스트>/mcp/vision/ビジョンのMCP
このパスはプロキシが何も開けてくれません

認証は後段が行います — /mcp/gateway/ はゲートウェイキー ppgw_…、直結MCP群は X-API-Key: <PI_INBOUND_API_KEY>、/llm/ は LiteLLM の マスターキーがなければ401です。基本ホストはたいてい 外部DNSが付いたアドレスなので、インストール後 CHANGE_ME_… で残ったキーがないか必ず確認してください → 資格情報管理

LiteLLM管理画面(/llm/ui)はこのパスでは開きません — :4000 で開いてください。

後段のインバウンドキー​

時系列インサイト・RAG・ドキュメント理解・ビジョン・デジタルスレッドは 同じインバウンドキー(インストールenvの PI_INBOUND_API_KEY)を使います → 資格情報管理。X-API-Key: <key> または Authorization: Bearer <key> で送ります。

  • キーなしで開くのは /ping · /health の2つだけです。/metrics もキーが必要です。

  • キーがないか間違っていれば 401 です(RAGは missing or invalid API key)。

  • 🔴 キーが空だとサービスが起動しません(fail-closed)。インストール点検(bin/lint-env.sh)が先に [fail] PI_INBOUND_API_KEY is empty and PI_INBOUND_AUTH_DISABLED is not true で止まり、サービスログには FATAL: … is empty — refusing to start … が残ります。空キーで«静かに開く後段»は発生しません。

  • 認証を意図的に切るには(隔離された試験環境など)インストールenvに PI_INBOUND_AUTH_DISABLED=true を書きます(デフォルト false)。composeがこの値を サービスごとの名前で渡します。

    サービスコンテナが読む名前
    RAGRAG_INBOUND_AUTH_DISABLED
    時系列インサイトTS_INBOUND_AUTH_DISABLED
    デジタルスレッドDT_INBOUND_AUTH_DISABLED
    ドキュメント理解・ビジョンINBOUND_AUTH_DISABLED

    キーが書かれていればキーが勝ちます(lint-envが [note] … is ignored — PI_INBOUND_API_KEY is set and the key wins で知らせます)。true · false 以外の値は [fail] です。切ったまま起動したサービスは /health にそうだと記されます(デジタルスレッド auth.inbound=disabled、時系列インサイト inbound_auth: "disabled") — 管理コンソールの APIキー 画面で 点検実行 すると 開放 として検出されます → AI管理コンソール — APIキー

ドキュメント理解・ビジョンはホストポート(7120・7130)を発行しません — 外部からは上記の /mcp/parser/ · /mcp/vision/ パスでのみ到達します。デジタルスレッド(7140)もホストポートを開きません。

MCPパスは末尾のスラッシュまでです

/mcp ではなく /mcp/ です。スラッシュを抜くとリダイレクトや404になります。


MCPプロトコル呼び出し​

5つのサーバーすべてが MCP(Model Context Protocol) 標準に従います。工場データ・オントロジー ツールはプラットフォーム統合MCP(/api/v5/mcp)、波形分析は時系列インサイト、文書・写真は残りの 3つです。

ツール名に接頭辞が付くのはチャットです

サーバーを直接呼ぶときは 接頭辞なしの名前(analyze_asset)を使います。insight_ のような 接頭辞はチャットのツール登録機が付けるものなので、チャット画面で見る名前とここで使う名前が 異なります。

MCP基本構造​

MCPは JSON-RPC 2.0 ベースのHTTP POST通信です。統合MCPはapi_key認証(Authorization: Bearer <token>)が必要です。

POST /api/v5/mcp HTTP/1.1
Content-Type: application/json
Authorization: Bearer <platform.api.token>

{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "<tool-name>",
"arguments": {
"<param1>": "<value1>",
"<param2>": "<value2>"
}
}
}

ツール一覧照会​

curl -X POST <platform>/api/v5/mcp \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <platform.api.token>" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list"
}'

ツール呼び出し例​

ほぼ常に search_domains から始まります

人は名前で話し、ツールはIDを受け取ります。search_domains が 14のドメインを 部分一致で検索して«ドメイン + ID»を確定し、そのIDを詳細ツールに渡すのが基本 手順です。

① 名前で探してIDを得る​

curl -X POST <platform>/api/v5/mcp \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <platform.api.token>" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "search_domains",
"arguments": {
"query": "압축기",
"domain": "asset",
"limit": 20
}
}
}'

domain がわかれば指定して精密検索し、わからなければ省略するとドメイン別に分けて返します。

② 資産階層を展開する​

curl -X POST <platform>/api/v5/mcp \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <platform.api.token>" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_asset_tree",
"arguments": { "asset_id": "<①에서 얻은 ID>" }
}
}'
tags キーがないのは«タグなし»ではありません

デフォルトではタグは 個数(tag_count)のみ 来ます。名前・tag_id が実際に必要なときだけ include_tags: true を与えてください — 応答が何倍も大きくなります。タグ有無の正本は tag_count で、tag_count: 0 のみが真のタグなしです。

③ タグ現在値を一度に読む​

curl -X POST <platform>/api/v5/mcp \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <platform.api.token>" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_tag_values",
"arguments": { "tag_ids": ["<tag_id>", "<tag_id>"] }
}
}'

tag_ids は配列で 一度に100個まで 入れます。応答の found: false は未登録 タグ、error は照会失敗(再試行する価値あり)を意味します。期間履歴は get_tag_history です。


統合MCP認証​

統合MCPは api_key認証が必須です。チャットが使う値はコパイロットの platform.api.url · platform.api.token(環境変数 CO_PLATFORM_API_URL · CO_PLATFORM_API_TOKEN — composeがホストenvの PP_API_URL · PP_API_TOKEN を移し入れます)です。 2026.09までの接頭辞 CH_ は2026.10に CO_ に変わり、フォールバックはありません。

⚠ 旧名称 mcp.api.url · mcp.api.token は ありません。 起動時に旧設定行が新名称へ 移されますが、環境変数を旧名称で与えても何も起こりません。

認証ヘッダー​

curl -X POST <platform>/api/v5/mcp \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <platform.api.token>" \
-d '{ ... }'

オントロジー(知識グラフ)呼び出し​

オントロジーツールは統合MCPに吸収されました。🔴 ontology_* という名前のツールは ありません — 旧独立サービス(:8888)時代の名前です。今は3つです。

ツール何を答えるか
get_ontology1サイトの構成概要 — 区域/ライン/設備構造 + 設備別タグ数
query_ontology方向性関係探索 — 「XがNに何に影響を与えるか」、上流・下流
query_sparql複数条件の交差質問(SELECT / ASK専用)

名前は似ていますが 返す軸が異なります。 純粋な階層構造は get_asset_tree、 サイト構成概要は get_ontology、関係伝播は query_ontology です。

サイト構成概要​

curl -X POST <platform>/api/v5/mcp \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <platform.api.token>" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_ontology",
"arguments": { "site_id": "<site_id>" }
}
}'

site_id は必須です — search_domains に domain: "site" で先に解決してください。

タグ総数は total_tag_count の一つが正本です

ノード別 tag_count を 合算しないでください — 展開していない枝が抜けます。 total_tag_count_unknown: true は「数えられなかった」という意味なので推測しないでください。

関係探索 — 「これが何に影響を与えるか」​

curl -X POST <platform>/api/v5/mcp \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <platform.api.token>" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "query_ontology",
"arguments": {
"entity_id": "<설비 ID>",
"direction": "DOWN",
"depth": 2
}
}
}'
引数値意味
entity_id(必須)探索を開始するエンティティ
relation_typeFEEDS · DEPENDS_ON · PRODUCES省略すると全体
directionUP · DOWN · BOTHデフォルト DOWN(下流影響)
depth1 ~ 5デフォルト2

応答は root + nodes[] + edges[] + truncated です。truncated: true なら深さや 幅で切られたという意味なので範囲を狭めて再質問します。


時系列インサイトMCP呼び出し​

設備異常検知​

curl -X POST http://127.0.0.1:8970/mcp/ \
-H "Content-Type: application/json" \
-H "X-API-Key: <PI_INBOUND_API_KEY>" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "detect_asset_anomaly",
"arguments": {
"asset_id": "ASSET_DJ_M_01_1",
"lookback_minutes": 1440,
"top_k": 5
}
}
}'

threshold を省略するとデフォルト 5.0 です。センサー異常スコアは0~1ではなく 補正スコア (基準区間対比ロバストz)なので、0 を与えると基準中央値より少し高いだけで全部異常として数えます → AIモデル

設備センサー予測​

curl -X POST http://127.0.0.1:8970/mcp/ \
-H "Content-Type: application/json" \
-H "X-API-Key: <PI_INBOUND_API_KEY>" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "forecast_asset",
"arguments": {
"asset_id": "ASSET_DJ_M_01_1",
"prediction_length": 96,
"enable_bounds": true
}
}
}'

設備健康スコア​

curl -X POST http://127.0.0.1:8970/mcp/ \
-H "Content-Type: application/json" \
-H "X-API-Key: <PI_INBOUND_API_KEY>" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_asset_health",
"arguments": {
"asset_id": "ASSET_DJ_M_01_1"
}
}
}'

RAG (LightRAG) 呼び出し​

RAGエンジンは LightRAG 1.5.7(2026.10から私たちがラップしたイメージ pi/plantpulse-lightrag)ですが、🔴 直接呼び出しません。 LightRAGはコンテナ 内にのみあり、外部から届く場所は rag-api(7115) ゲートウェイ一つです。

文書アップロード・一覧・削除は 管理コンソールで行います(旧LightRAG WebUIはコンソールに吸収されました)。 検索はゲートウェイのRESTで呼び、X-API-Key で認証します。

備考

コパイロットチャットの文書検索は、このゲートウェイの MCP ツール rag_search を MCP ゲートウェイ経由で 呼びます(コパイロットに 内蔵の文書検索はありません)。REST /api/v1/query と MCP rag_search は 同じ封筒 を返します — LightRAGに 直接繋がりません。下記の応答形はLightRAGのものではなく ゲートウェイが定めた封筒です。

テキスト検索​

curl -X POST http://127.0.0.1:7115/api/v1/query \
-H "Content-Type: application/json" \
-H "X-API-Key: <PI_INBOUND_API_KEY>" \
-d '{
"query": "펌프 정비 절차",
"mode": "hybrid"
}'
引数値
query検索語 — 3文字以上(短いと400)
modehybrid(デフォルト) · naive · local · global — それ以外の値は 422
応答意味
{"retrieved": true, "answer": …, "sources": [{"file_name": …, "reference_id": …}]}見つかりました。reference_id は答本文の出典表示 [n] のnです(エンジンが番号を付けなかった出典にはありません)
{"retrieved": false, "code": …, "reason": …, "sources": []}見つかりませんでした。 answer キー自体がありません
HTTP 502エンジン側の失敗
retrieved: false はエラーではなく«ない»です

HTTPは200です。code が NO_CONTEXT なら索引済み文書に関連内容がないということで、 EMPTY_ANSWER ならエンジンが空手で戻ってきたということです。再度呼んでも同じ答えが来ます — answer がない応答を結果のように見せないでください。


図面比較 — 二つの版の差分​

図面収集(DRAWING_INGEST_ENABLED=true)を有効化したインストールで使えます → 環境変数設定。 入口は二つで、比較はドキュメント理解が行います。 rag-apiは索引済みの二つの版の原本を取り出してドキュメント理解に渡し、その結果を そのまま返します。両方ともインバウンドキーを受けます。

入口いつ
rag-api GET /api/v1/drawings/{asset_id}/{doc_name}/diff既に索引済みの図面 — 前版を探して比較します
ドキュメント理解 POST /api/v1/drawings/diff手元にある ファイル二つ を直接比較します(索引と無関係)

索引済み図面の前版と比較(rag-api)​

curl -G "http://127.0.0.1:7115/api/v1/drawings/<asset_id>/<doc_name>/diff" \
-H "X-API-Key: <PI_INBOUND_API_KEY>" \
--data-urlencode "lang=ko"
引数意味
against比較する前版の文書名。空なら 同じ図面番号 のうち版表示が直前のもの(A < B < … < Z < AA、1 < 2 < 10)を選びます
against_asset前版が別の設備に載っている場合の設備ID(デフォルト同じ設備)
langsummary 行の言語 ko · en。空ならインストール言語(PP_LANG)。数字は言語に関係なく図面に書かれたままです
状態意味
404どちらかが索引されていないか、原本が保管されていないか、選ぶ前版がない
422比較器がファイルを読めない
502比較器やオブジェクトストレージに届かない

同じルーターにページプレビュー(…/page/{n} — PDFはPNG、DXFはSVG)と版状態(…/revision-status — current · outdated · change_open · unknown)があります。

ファイル二つを直接比較(ドキュメント理解)​

ドキュメント理解はホストポートを発行しないので外部からは parser.* ホストで呼びます。

curl -X POST "https://parser.<domain>/api/v1/drawings/diff" \
-H "X-API-Key: <PI_INBOUND_API_KEY>" \
-F "old=@A-100_rev-A.dxf" -F "new=@A-100_rev-B.dxf" -F "lang=ko"
  • ファイルは .dxf やテキスト層があるベクター .pdf、1つあたり 50 MB までです。DWGは受け付けません。
  • lang のデフォルト値は en です(rag-api入口とは異なります)。
  • 拒否は error_kind: input とともに拡張子 415 · サイズ 413 · 読めない 400 です。

結果の形​

キー入れるもの
title変わった表題欄のセル
dimensionsadded · removed · changed(値・単位・個数・公差・文字・位置のうち何が変わったか)· unchanged
bom · notes変わったBOM行・注記
regions変わった領域 — 後版の bbox と前版の bbox_old。合わせに失敗すると status: unavailable と理由で、領域を捏造しません
summary人が読む要約行 — 数字は図面の文字そのまま
confidence · limitshigh · medium · low と、比較できなかったもの(スキャン側・表題欄なし・片方のみBOMなど)
warningsdifferent_drawing_numbers(図面番号が異なる)· revision_label_unchanged(版表示が同じ)など

動画・音声 — rag-apiの/api/v1/media​

動画・音声収集を有効化したインストール(インストールenv PI_MEDIA_ENABLED=true)でのみ付くパスです。無効なインストールにはこのパスが全く無く 404 で、 動画・音声アップロードは 400 で拒否されます。有効かどうかは GET /api/v1/config の media_ingest_enabled で見ます → 環境変数設定 · AI管理コンソール — 動画

メソッド・パス行うこと
GET /api/v1/media/jobsファイルごとの処理状態・長さ・区間数・シーン画像数(thumb_count)と処理時間帯(window — open · next_start · spec)
GET /api/v1/media/jobs/{asset_id}/{doc_name}ファイル1つの詳細
GET /api/v1/media/integrity索引済みだが検索索引にない区間
POST /api/v1/media/jobs/{asset_id}/{doc_name}/retry再度キューに(失敗・スキップ)。?force=true なら最初から再文字起こし
GET /api/v1/media/{asset_id}/{doc_name}/transcript保管された文字起こし
GET /api/v1/media/{asset_id}/{doc_name}/thumb?t=<ms>その時刻以前の最も近いシーン画像
GET /api/v1/media/{asset_id}/{doc_name}/stream再生 — Range リクエストに206で応答します
  • アップロードは文書と同じ POST /api/v1/docs/upload で、削除も同じ DELETE /api/v1/docs/{asset_id}/{doc_name} です(プラットフォーム台帳から来たものは 409)。
  • シーン画像(…/thumb) は ETag と Cache-Control: private, max-age=86400 を付けます。同じ ETag を If-None-Match で送ると 画像を再度読まずに 304 で応答します。状態DBが一時的に忙しいと500ではなく 503 state database busy, retry shortly と Retry-After: 1 です — その後再度呼んでください。
  • コパイロット画面が使う中継(コパイロットの /media/thumb · /media/stream、ログインセッション認証)も ETag · 304をそのまま渡し、後段の503は Retry-After とともに503として渡します(以前は502で包んでいました)。

リクエストidと指標 — X-Request-ID · /metrics​

2026.10再リリースからPythonの後段5つ(RAG・時系列インサイトAPI・ドキュメント理解・ビジョン・デジタルスレッド)が同じ規則を使います。

  • リクエストid — リクエストに X-Request-ID(1~128文字、英数字・. _ -)を乗せて送るとその値を、ないか形が違えば 新しく作った値を応答ヘッダー X-Request-ID で返します。そのリクエストが処理されている間残るログ行に同じ値が request_id で付きます。RAGはエラー応答本文にも request_id を加えます。
  • 指標 — GET /metrics がPrometheusテキスト形式を出します。インバウンドキーが必要です(ヘルスパスと違い免除 ではありません)。ポートは変わっていません → ログ及びモニタリング
curl -s -D - -o /dev/null -H "X-Request-ID: my-trace-001" \
-H "X-API-Key: <PI_INBOUND_API_KEY>" http://127.0.0.1:7115/api/v1/config | grep -i x-request-id

LLM API 呼び出し (OpenAI互換)​

LiteLLMプロキシは OpenAI互換API を提供します。既存のOpenAI SDKをそのまま使えます。 LANでは http://<server>:4000/v1、基本ホストを経由すると https://<호스트>/llm/v1 です。

チャット補完​

curl http://127.0.0.1:4000/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer 설치-시-변경" \
-d '{
"model": "aura-lite",
"messages": [
{"role": "user", "content": "주입기 베어링 교체 주기를 알려줘."}
],
"temperature": 0.7
}'

埋め込み生成​

curl http://127.0.0.1:4000/v1/embeddings \
-H "Content-Type: application/json" \
-H "Authorization: Bearer 설치-시-변경" \
-d '{
"model": "aura-embedding-4b",
"input": "주입기 베어링 교체 절차"
}'

モデル一覧確認​

curl http://127.0.0.1:4000/v1/models \
-H "Authorization: Bearer 설치-시-변경"

利用可能なモデル​

モデル名用途実際のモデル
aura-lite会話・分析(画像入力兼用)Aura — デフォルト Aura-Lite-NVFP4
aura-vision上と同じエンジンのビジョン用エイリアス上と同じモデル
aura-embedding-4b埋め込みAura-Embedding-4B
aura-reranker-0.6bリランキングAura-Reranker-0.6B
旧名称 gpt-4o · text-embedding-3-large は今はエラーです

以前の版はOpenAI互換エイリアス(gpt-4o · gpt-4o-mini · text-embedding-3-large · rerank-multilingual-v3.0)を受け付けていました。今は受け付けません — 連携コードに旧名称が 残っていると呼び出しが拒否されます。上表の名前に変更してください。今立ち上がっている名前は /v1/models で確認できます。

どの名前でも 社内で動くAuraモデルに行きます — 閉域網インストールでも同じです。


Python SDK 例​

OpenAI SDKでLLM呼び出し​

from openai import OpenAI

client = OpenAI(
base_url="http://127.0.0.1:4000/v1",
api_key="설치-시-변경"
)

response = client.chat.completions.create(
model="aura-lite",
messages=[
{"role": "user", "content": "주입기 상태를 분석해줘."}
]
)

print(response.choices[0].message.content)

MCPツール呼び出し​

import requests

def call_mcp_tool(url, tool_name, arguments=None, headers=None):
response = requests.post(
url,
headers=headers or {},
json={
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": tool_name,
"arguments": arguments or {}
}
}
)
return response.json()

# 이름으로 설비를 찾는다 (통합 MCP — api_key 필요)
result = call_mcp_tool(
"<platform>/api/v5/mcp",
"search_domains",
{"query": "압축기", "domain": "asset"},
headers={"Authorization": "Bearer <platform.api.token>"}
)
print(result)

# 설비 이상 탐지 (TimeSeries-Insight — 인바운드 키 필요)
result = call_mcp_tool(
"http://127.0.0.1:8970/mcp/",
"detect_asset_anomaly",
{"asset_id": "ASSET_DJ_M_01_1", "lookback_minutes": 1440},
headers={"X-API-Key": "<PI_INBOUND_API_KEY>"}
)
print(result)

コパイロット公開API (/api/v1)​

外部システムが チャットと朝カードをそのまま使う 入口です。チャットと同じアドレス(基本ホスト)に あります。

メソッド・パス行うこと
POST /api/v1/chat質問して答えを受け取ります。必要なツールはサーバーが選びます
GET /api/v1/tasks/dailyその日のデイリーカード(毎日05:00生成)を読みます。?date=YYYY-MM-DD — 工場タイムゾーン基準、空なら今日
GET /api/v1/toolsエージェントが今使えるツール一覧(名前・説明・照会専用か否か)
GET /api/v1/ai-feedback人がAI結果に付けた表示(誤報・提案の受諾/拒否/効果)とサーバーが規則で付けた表示(正しい・誤報・見逃し)を読みます — 2026.10(下記)
curl -X POST https://<호스트>/api/v1/chat \
-H "Content-Type: application/json" \
-H "X-API-Key: <발급받은 키>" \
-d '{ "input_value": "지금 끊어진 엣지 장비가 몇 대야?" }'

応答は answer(マークダウン)· session_id · duration_ms · tools(この答えを作るために呼んだツール) です。session_id を抜くか空にすると新しい会話を開き(画面の「新しい会話」と同じ — デフォルトアプリ、呼んだ 人の所有)、そのidを応答の session_id で返します。会話を継続するには次のリクエストにその値を入れます。 同期呼び出しなのでツールを複数回呼ぶ質問は数十秒かかることがあります。

2026.09版では session_id なしの呼び出しが500でした

文書は「空なら新しい会話」としていましたがサーバーが500を出し、X-API-Key で呼んだ呼び出しも500で終わりました。 2026.10で両方修正されました。

答えが空なら502です

2026.10再リリース3からモデルが再試行した後も答えを作れなければ HTTP 502 で返します。本文の形は同じで answer が空です。 空の答えを200で受けて«答えなし»を結果のように見せないようにしたものです — 同じ質問を再送すればよいです。

AI結果に人が付けた表示 — GET /api/v1/ai-feedback​

コパイロットの提案で人がAI結果に付けた表示(無視理由・受諾/拒否・効果)を読むだけの入口です(書く経路は画面のみです) → AI発見と精度 — 人が残す判断。認証は 他の /api/v1 と同じです(X-API-Key のみ — 2026.10再リリース6からログインセッションは403)。

curl "https://<호스트>/api/v1/ai-feedback?since=2026-10-01T00:00:00Z&limit=500" \
-H "X-API-Key: <발급받은 키>"
引数意味
sincelabeled_at 下限(RFC 3339またはepoch ms)。空なら最初から
asset_id設備idでフィルタします
target_kindANOMALY(異常1件)· FINDING(AI発見)· PROPOSAL(発見から生まれた提案カード)· MISSED(見逃し報告)· DAILY_TASK
limit最大行数1~1000、デフォルト500

応答は count · items · next_since です。古いものから来るので 次ページは next_since で再度 呼びます — 同じ時刻の行が重なって来ることがあるので feedback_id でフィルタしてください。同じ対象に人が再度押すと その行の value · labeled_at が変わります(最後の表示が勝ちます)。

label_keyvalue
verdicthit · false_alarm · unsure(判定保留 — 精度計算から除外します)
reason誤報理由 setup · idle · maintenance · sensor · other / 提案拒否理由 already_done · not_needed · wrong · other
cause実際の原因 breakdown · degradation · sensor · setup · maintenance · normal · other
proposal_decisionaccepted · rejected
outcomeeffective · not_effective · unknown (comment にメモ)
missedmissed (comment に説明、occurred_at に見逃した事件時刻)

新しい画面(メニュー3つ)で人が残す値は verdict の false_alarm(確認すべき異常の無視)とその reason、proposal_decision、outcome です。 hit · missed はサーバーの停止・故障規則照合が付け、unsure · cause は旧画面で残した行にあります。

各行には occurred_at(表示が指す事件時刻)· labeled_by · labeled_at · config_ver(その結果を 出した判定バージョン)が一緒に来て、時刻横の …Stamp は工場タイムゾーン(PP_TZ)で書いた値です。

キー — 二つの方法​

方法どこで性質
発行キー(推奨)コパイロット管理コンソール → APIキー → 発行名前を付けて複数発行し 1つずつ廃棄できます。最終使用時刻が残ります
環境変数キー/etc/kopens/plantpulse-ai.env の CO_API_V1_KEY(2026.09まで CH_API_V1_KEY — 旧名称は静かに無視されます)1行のみです。空にするとこのキーでの認証のみが無効になります
発行キーは«発行直後一度»だけ表示されます

保存はハッシュのみで行うため一覧には先頭文字のみが表示されます。失くしたら新規発行して旧いものを 廃棄してください。

このキーで届く場所は公開APIのみです

キーが与える権限は /api/v1 とコパイロットMCP(/mcp)です。2026.10再リリース6からこの二つのパスはキーのみで開き、 ログイン済みブラウザセッションで呼ぶと403です。キーで呼んだ呼び出しの権限・文書等級は«外部API»役割群(デフォルト対外秘)に従い 範囲は常に全体です → 権限。管理者パスとAPI文書 画面(/swagger-ui.html)は管理者ログインが必要です。ツールを«直接呼ぶ»経路は 開いていません — 状態を変えるツールには人の承認手続きが付いているためです。

画面が使うAPIのうち変わったもの(2026.10再リリース3)​

以下は公開APIではなくコパイロット画面がログインセッションで呼ぶパスです。画面を真似て呼ぶ連携があれば確認してください。

メソッド・パス変わったこと
PUT /api/employees/{아이디}/work-role🔴 管理者のみになります(以前は本人もできました)。本文 {"workRole": "maintenance"}。変更のたびに監査ログに employee.work_role:<아이디> として残ります → ユーザー権限と業務ロール
PUT /api/employees/{아이디}/home-role新しいパス — 本人の開始画面設定。本文 {"homeRole": "manager"}(業務ロールと同じ5つの値)。本人または管理者が呼びます。承認権限は変えません。メニュー3つ(質問・提案・自動化)の新画面は最初の画面が誰にとっても質問なのでこの値を使いません — パスは残っています
GET /api/sop?query=…&assetId=…assetId 引数が追加されました — 与えると**別の設備の出典を除きます。**応答は {answer, sources[], citations, truncated} で答えは600字以内の文境界で切ります(truncated)。検索語が短すぎると400、文書検索サービスが応答しなければ503 + Retry-After です

応答形式​

MCP成功応答​

{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "{ ... 도구 실행 결과 JSON ... }"
}
]
}
}

MCPエラー応答​

{
"jsonrpc": "2.0",
"id": 1,
"error": {
"code": -32600,
"message": "Invalid request",
"data": "상세 오류 메시지"
}
}

量が多い時 — limit と has_more​

🔴 page · size はありません。 統合MCPツールは limit で上限を与え、応答の has_more で「まだある」を知らせます。

{
"name": "search_domains",
"arguments": {
"query": "압축기",
"domain": "asset",
"limit": 50
}
}
ツールlimit デフォルト値最大値
search_domains50500
get_tag_history500500
get_tag_values(配列 tag_ids — 一度に)100個
has_more: true に出会ったら

ページ番号がないので 条件を絞ることが基本です — domain を指定するか期間を 区切るか検索語を具体化してください。同じクエリを押し続けて次ページを受け取る形ではありません。


時刻形式​

統合MCPの時刻パラメータは サーバーローカル時刻です。名前は from · to で、 形式は YYYY-MM-DDTHH:MM:SS です。

{
"name": "get_tag_history",
"arguments": {
"tag_id": "<tag_id>",
"from": "2026-03-29T00:00:00",
"to": "2026-03-29T23:59:59"
}
}
オフセットと Z を付けると拒否されます

2026-03-29T00:00:00+09:00 や ...Z は 受け付けません。 オフセットなしのローカル時刻のみ 受け付けます — サーバーが今何時だと認識しているかは get_current_time で確認してください。

start_time · end_time という名前もありません。from · to です。

応答で _iso 接尾辞が付いたフィールドは人が読みやすいKST形式です:

{
"timestamp": 1711641600000,
"timestamp_iso": "2026-03-29 09:00:00"
}