@flyle/ai-contact-center-mcp 0.0.0 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,111 +1,66 @@
1
1
  # @flyle/ai-contact-center-mcp
2
2
 
3
- Flyle AIコンタクトセンターの公開 API を、Claude Code などの MCP クライアントから呼ぶための **stdio MCP サーバー**。npm に公開するので、利用者はこのリポジトリを用意せず `npx` で起動できる。
4
- 公開 API の OpenAPI スナップショット(`apps/flygate/backend-ecs/public-api/openapi/v0.json`)から生成した操作表 `src/generated/manifest.json` の 1 行 = 1 ツール。表に無い操作は呼べない(任意 URL / 任意メソッドのプロキシは持たない)。
3
+ Flyle AIコンタクトセンターを Claude Code などの MCP クライアントから操作するための MCP サーバーです。ブラウザでご自身のアカウントにログインし、**ご自身のロールの権限の範囲で**エージェントの設定・検証などを行えます。
5
4
 
6
- 現在は試験的提供で、API キーを発行できるのは Flyle 社内メンバー(flyle.io ドメインのアカウント)に限られる。
5
+ > [!NOTE]
6
+ > 試験的な提供です。現在は Flyle 社内メンバー(flyle.io ドメインのアカウント)に限定しています。仕様が変わる場合があります。
7
7
 
8
- MCP では、エージェントの設定取得・編集から、ナレッジやファイルの取り込み、プレビューの作成と完了確認、検証ケースの管理と試行、検証の実行・結果取得、改善分析と設定の再調整までを進められます。編集後はプレビューの作成完了を確認してから検証し、結果を確認して再調整してください。公開の実行・昇格・取消は提供していません(公開状態の参照は可能)。
8
+ 詳しい使い方は、ご利用ガイドの「[公開 API で外部システムと連携する](https://guide.flyle.io/ja/flygate/public-api)」をご覧ください。
9
9
 
10
- `get_knowledge_document_original_content` はナレッジ原本を `FLYLE_AI_CONTACT_CENTER_MCP_OUTPUT_DIR` へ自動保存し、ファイルパスを返します。PDF / DOCX / PPTX などの本文は保存したファイルで確認します。Markdown / HTML / テキスト形式は、自動保存に加えて本文も応答の `text` に含まれます。
10
+ ## 必要なもの
11
11
 
12
- 一覧の取得方式は各ツールの入力スキーマと応答に従います。cursor、limit と offset、ページングなしの全件取得があります。
12
+ - Node.js 22 以上
13
+ - テナント設定「外部ツールからのログイン接続」が許可されていること(「設定」>「テナント」)
14
+ - ご自身のロールに「外部ツール接続」の権限があること
13
15
 
14
- 改善要望の検証は、現在の設定・既存ケースの取得 → `create_eval_case` / `import_eval_cases` でケースを保存 → 変更前の検証 → 設定の修正または改善提案の選択適用 → プレビュー作成完了の確認 → 全ケースの再検証、の順に進めます。`create_improvement_analysis` は分析結果を返す操作で、ケースや設定の保存は行いません。提案の内容と適用プランを確認し、根拠のない条件を追加する変更は採用しないでください。実行受付後は `get_eval_run` と `list_eval_run_case_results` で完了と成否を確認します。
16
+ ## はじめかた
15
17
 
16
- ファイル取込では `inspect_local_file` の `sizeBytes` を API の `byteSize`、`sha256Hex` を `checksumSha256` に渡します(`sha256Base64` ではありません)。同じ MCP 接続でアップロード URL を発行して `upload_file` を呼び、続けて `create_knowledge_import` を実行します。転送成功とナレッジ取込完了は別なので、取込と文書の処理状況も確認してください。
18
+ 1. テナント専用の作業ディレクトリを用意します。1 つのディレクトリは 1 つのテナント専用になります。ホームディレクトリは使えません。
17
19
 
18
- ## 実行契約
20
+ ```sh
21
+ mkdir acme-corp && cd acme-corp
22
+ ```
19
23
 
20
- | 項目 | 内容 |
21
- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
22
- | 認証先 | `FLYLE_AI_CONTACT_CENTER_API_BASE_URL` の origin だけに `Authorization: Bearer <key>` を送る。3xx は追跡しない |
23
- | テナント | `FLYLE_AI_CONTACT_CENTER_TENANT_NAME` で固定。ツール引数に `tenantName` は無く、渡すと入力検証で弾く。全ツール結果の先頭(`content[0]`)に `{"tenantName": …}` を出し、サーバー説明文にも接続先を書く |
24
- | 作業ディレクトリ | 起動時の作業ディレクトリ(cwd)を 1 テナント専用に束縛する(`.flyle-ai-contact-center-mcp/workspace.json` を排他作成)。別テナントに束縛済み・別テナントの作業ディレクトリの入れ子・ホームディレクトリ / ルートでは起動しない。操作ごとに束縛を確かめ、書き換えられていたら実行しない。`OUTPUT_DIR` / `FILE_ROOTS` は作業ディレクトリの中に限り、読むファイルも作業ディレクトリ内の別テナントの束縛配下なら拒否する。公開 API には作業ディレクトリの不透明 ID(ホスト名・OS ユーザー・realpath の sha256)を `x-flyle-client-workspace` で送り、サーバーが「同じ作業ディレクトリから 2 テナント」を検知する(設計書 §7.4) |
25
- | 再送 | GET の JSON / 空応答だけ、429(`Retry-After` ≤ 30 秒)と接続失敗で 1 回。書き込み(POST / PUT / PATCH / DELETE)は一切再送しない |
26
- | SSE | `x-response-kind: sse` の操作は終端まで収集してイベント列で返す(上限 15 分 / 10,000 イベント / 32 MiB。超えたら `truncated: true` と理由)。空行で確定していない末尾イベントは WHATWG どおり捨て、`discardedIncomplete: true` で伝える |
27
- | binary | ZIP 等は `FLYLE_AI_CONTACT_CENTER_MCP_OUTPUT_DIR` に保存し、パス・バイト数・sha256 を返す |
28
- | 署名付き URL | `x-transfer` の pointer が指す位置の URL だけを使う(注記の無い操作は本文中の URL を一切転送先にしない)。download はその場で保存(保存に失敗しても API 応答は返し、結果の `failedDownloads` に失敗種別を記して `download_file` で再試行できるよう登録する)、upload は `upload_file` ツール向けに 15 分・1 回限りで登録。認証ヘッダは付けず、ホストは `FLYLE_AI_CONTACT_CENTER_MCP_STORAGE_HOSTS` の許可リストに限る |
29
- | ローカルファイル | `inspect_local_file` / `upload_file` が読めるのは `FLYLE_AI_CONTACT_CENTER_MCP_FILE_ROOTS` 配下だけ(シンボリックリンク越えも realpath で拒否。検証から open までに親ディレクトリを差し替える並行ローカル主体は脅威モデルに含めない) |
30
- | 本文埋め込みファイル | `x-inline-files` の pointer が指す位置だけを扱う。入力(例 `create_preview_voice_turn` の `audio`、`create_preview_chat_turn` の `transcript[*].images[*].base64Data`)はツール引数にローカルファイルのパスを受け、MCP が読んで base64 にして送る(WAV は PCM 16bit / 24 kHz / mono をヘッダで検証、PCM 2 MiB 以内。画像はプレビューチャットが 10 MiB 以内、検証用画像(`create_eval_image`)が 2 MiB 以内)。出力(SSE の `audio_delta`、JSON 応答の `create_web_chat_voice_sample` の `voiceSample.audioChunks[*]`。いずれも PCM16LE / 24 kHz / mono)は連結して `FLYLE_AI_CONTACT_CENTER_MCP_OUTPUT_DIR` に WAV で保存し、結果にはパス・バイト数・sha256・再生時間だけを返す(JSON 本文側の base64 は保存先の案内文に置き換える。累積 32 MiB 上限) |
31
- | SSE の成否 | `x-sse-outcome` を持つ操作は HTTP 200 / EOF だけで成功にしない。最初の終端イベント(例 `closed`)で判定を確定し、その前に必須イベント(例 `turn_done`)が揃い、失敗イベント(`error`)が無く、値比較を指定した契約では終端の値が成功値(`code=1000`)のときだけ `outcome: success`。正常終端前の `error` は終端欠落時も `failed`。失敗イベントも正常終端も無い EOF・打ち切りは `unknown`、異常終端は `failed` で、いずれも `isError: true`・自動再送なし |
32
- | エラー | 公開 API の封筒 `{ error: { code, message, detail, requestId } }` を `isError: true` の構造化 payload でそのまま返す。API キーは stderr・payload のどこにも出さない |
33
- | ログ | stdout は JSON-RPC 専用。ログは stderr に JSON 行(鍵は置換) |
24
+ 2. そのディレクトリでログインします。ブラウザが開くので、同意画面で接続先のテナント・環境と操作できる範囲を確認して許可してください。
34
25
 
35
- ## 設定(環境変数)
26
+ ```sh
27
+ npx @flyle/ai-contact-center-mcp login --tenant <テナント名>
28
+ ```
36
29
 
37
- | 変数 | 必須 | 説明 |
38
- | ------------------------------------------------- | ---- | --------------------------------------------------------------------------------------------------------------- |
39
- | `FLYLE_AI_CONTACT_CENTER_API_BASE_URL` | ✔ | 公開 API の URL(https)。例 `https://api.flygate.flyle.io` |
40
- | `FLYLE_AI_CONTACT_CENTER_TENANT_NAME` | ✔ | テナント名(URL の `/v0/tenants/{tenantName}`) |
41
- | `FLYLE_AI_CONTACT_CENTER_API_KEY` | ✔ | サービスアカウントの API キー(`flyle_ai_contact_center_sa_…`) |
42
- | `FLYLE_AI_CONTACT_CENTER_MCP_OUTPUT_DIR` | | ダウンロード先(作業ディレクトリ内に限る)。既定 `.flyle-ai-contact-center-mcp/downloads` |
43
- | `FLYLE_AI_CONTACT_CENTER_MCP_FILE_ROOTS` | | アップロード元として読める根ディレクトリ(カンマ区切り。作業ディレクトリ内に限る)。既定は作業ディレクトリ |
44
- | `FLYLE_AI_CONTACT_CENTER_MCP_STORAGE_HOSTS` | | 署名付き URL のホスト許可リスト(`.amazonaws.com` のようなサフィックス、または完全一致)。既定 `.amazonaws.com` |
45
- | `FLYLE_AI_CONTACT_CENTER_MCP_ALLOW_INSECURE_HTTP` | | `1` で localhost への http を許す(ローカル開発専用) |
30
+ 3. 同じディレクトリに `.mcp.json` を置き、Claude Code を起動します。
46
31
 
47
- ### Claude Code への登録例
32
+ ```json
33
+ {
34
+ "mcpServers": {
35
+ "flyle-ai-contact-center": {
36
+ "command": "npx",
37
+ "args": ["-y", "@flyle/ai-contact-center-mcp"]
38
+ }
39
+ }
40
+ }
41
+ ```
48
42
 
49
- テナントごとにディレクトリを分け(例 `~/flyle-cs/acme-corp`)、そのディレクトリの `.mcp.json`(project scope)に登録する。ユーザー scope(`~/.claude.json`)には置かない。サーバー名にテナント名を入れると Claude Code のツール名(`mcp__flyle-acc-acme-corp__…`)にも出る。
43
+ Claude Code を起動したままログインした場合は、`/mcp` から MCP サーバーを再接続してください。
50
44
 
51
- ```json
52
- {
53
- "mcpServers": {
54
- "flyle-acc-acme-corp": {
55
- "command": "npx",
56
- "args": ["-y", "@flyle/ai-contact-center-mcp"],
57
- "env": {
58
- "FLYLE_AI_CONTACT_CENTER_API_BASE_URL": "https://api.flygate.flyle.io",
59
- "FLYLE_AI_CONTACT_CENTER_TENANT_NAME": "acme-corp",
60
- "FLYLE_AI_CONTACT_CENTER_API_KEY": "flyle_ai_contact_center_sa_..."
61
- }
62
- }
63
- }
64
- }
65
- ```
45
+ ## コマンド
66
46
 
67
- ## ツールの構成
47
+ 作業ディレクトリで実行します。
68
48
 
69
- - **API 操作ツール**: `operationId` がそのままツール名(`list_agents` / `update_agent` / …)。入力 schema はパス変数・クエリ・ボディを 1 つのオブジェクトに平坦化したもの。`components` への参照は `$defs` に写して自己完結させる(再帰 schema を展開で壊さない。未定義の参照は生成時に例外)。
70
- - 説明文に `HTTP: METHOD path`、必要権限(`x-permission`)、効果(`x-effect`: read / draft)、応答種別、再送禁止の注記を載せる。
71
- - `annotations`: GET は `readOnlyHint`、DELETE は `destructiveHint`、GET / PUT / DELETE は `idempotentHint`。
72
- - 本番へ即時反映する操作(`x-effect: live`。資格情報・秘密情報・電話番号・SIP・エージェント削除など)はツールにしない。複数顧客を扱う作業で誤操作が直ちに本番へ出るのを防ぐため。マニフェスト生成時に除外し、読み込み時も live を拒否する。
73
- - **ローカルツール**: `inspect_local_file`(名前・サイズ・sha256 hex / base64・MIME)、`upload_file`(登録済み URL へ PUT)、`download_file`(登録済み URL から保存)。
49
+ | コマンド | 内容 |
50
+ | -------------------------------------------------------------- | ---------------------------------------------------------------- |
51
+ | `npx @flyle/ai-contact-center-mcp login --tenant <テナント名>` | ブラウザでログインします。2 回目以降は `--tenant` を省略できます |
52
+ | `npx @flyle/ai-contact-center-mcp status` | ログイン中のテナント・環境と有効期限を表示します |
53
+ | `npx @flyle/ai-contact-center-mcp logout` | ログアウトし、この作業ディレクトリの接続を切断します |
74
54
 
75
- ## 配布
55
+ ログインは最後に使ってから 30 日間有効で、使うたびに延長されます。ご自身の接続は管理画面の「設定」>「外部ツール接続」から確認・切断できます。
76
56
 
77
- npm 公開パッケージなので、実行時に未公開の workspace 依存が残っていてはならない。`rolldown` で `dist/main.js` 1 枚に畳み、`@flyle-lib/utils` は畳み込む(`@modelcontextprotocol/server` は公開パッケージなので利用者側で解決させる)。
57
+ ## できること・できないこと
78
58
 
79
- ```sh
80
- pnpm -F @flyle/ai-contact-center-mcp build
81
- ```
59
+ - エージェントの設定の取得・編集、ナレッジやファイルの取り込み、プレビューの作成、検証ケースの管理と検証の実行、改善分析などを行えます。
60
+ - 公開の実行・昇格・取消など、本番の応対に直接影響する操作は提供していません(公開状態の参照はできます)。
61
+ - ツールがダウンロードしたファイル(ナレッジ原本・音声など)は、作業ディレクトリの `.flyle-ai-contact-center-mcp/downloads` に保存されます。
62
+ - アップロードなどで読み込めるのは、作業ディレクトリの中のファイルだけです。
82
63
 
83
- 操作表は実行時に `import.meta.url` からの相対で読むため、build が `generated/manifest.json` へ複製する(`files` はこの `dist` と `generated`)。
64
+ ## 以前の設定から移行する
84
65
 
85
- ## 操作表の更新
86
-
87
- ```sh
88
- pnpm -F @flyle/ai-contact-center-mcp manifest:generate # openapi/v0.json → src/generated/manifest.json
89
- pnpm -F @flyle/ai-contact-center-mcp manifest:check # CI 用。古いと非 0
90
- ```
91
-
92
- OpenAPI 側で使う拡張は `x-response-kind`(json / empty / sse / binary)、`x-effect` と `x-live-impact`、`x-transfer { kind, urlPointer, headersPointer }`、`x-inline-files { input: [{ pointer, format: wav-pcm16 | base64, maxBytes, sampleRateHz?, channels? }], output: [{ event?, pointer, format: pcm16le | base64, sampleRateHz?, channels?, mediaType? }] }`、`x-sse-outcome { requiredEvents, terminalEvent, successPointer, successValue, failureEvents }`。無い操作は content-type から応答種別を推定し、効果は「注記なし」として扱う。`oneOf` の判別共用体ボディ(例 `create_knowledge_import`)は平坦化せず `body` 引数で全体を受ける。upload の PUT ヘッダは `headersPointer` が指す `uploadHeaders` だけを使う。
93
-
94
- ## テスト
95
-
96
- ```sh
97
- pnpm -F @flyle/ai-contact-center-mcp test
98
- ```
99
-
100
- `tests/stdio.e2e.spec.ts` は `node src/main.ts` を子プロセスで起動し、偽の公開 API に対して initialize → tools/list → tools/call を通す。SDK の client パッケージには依存せず、行区切り JSON-RPC を直接話す。
101
-
102
- ## 大きな結果と SSE の完了判定
103
-
104
- 整形・秘密情報の伏せ字化後の JSON が 1,048,576 文字を超える場合、全文を compact JSON(改行なし)で `FLYLE_AI_CONTACT_CENTER_MCP_OUTPUT_DIR` に `<時刻>-<乱数>-<ツール名>.result.json` として排他作成します(1 ファイル 64 MiB まで)。ツール結果には保存先・バイト数・sha256・`format: "json"` と、整形表記の総文字数・先頭 4,096 文字(`preview`)を返します。全文は保存ファイルで確認してください。保存に成功した場合、元の `isError` は変わりません。保存に失敗した場合(書込不可・64 MiB 超過など)は `isError: true` で `error.kind = "result_not_saved"` と失敗種別を返し、`preview` と総文字数はそのまま同梱します。stderr に失敗種別だけを warn ログで残します。操作の状態を確認してから再実行してください。
105
-
106
- `x-sse-outcome` の `successPointer` と `successValue` が両方 `null` の契約は、値比較をせず正常終端イベントで完了を判定します。チャットのプレビューは `done`、検証ケースの試行・改善分析・コネクター支援は `result` が正常終端です。検証品質の `finalStatus: FAILED` は試行自体の失敗ではありません。正常終端前の `error` は処理失敗、終端を確認できない切断・上限到達は結果不明として返し、自動再送しません。
107
-
108
- ## 依存
109
-
110
- - `@modelcontextprotocol/server`(MCP TypeScript SDK v2。`fromJsonSchema` で JSON Schema をそのままツール入力に使うので zod は不要)
111
- - `@flyle-lib/utils`(devDependencies。バンドルへ畳み込むので利用者には配らない)
66
+ 以前の版で `.mcp.json` の `env` に書いていた API キー・接続先・テナント名などの環境変数は使えなくなりました。`env` を削除し、上の手順でログインしてください。残っていると、MCP サーバーは変数名を示して起動を止めます。