ireporter-mcp 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.
Files changed (129) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +265 -0
  3. package/dist/client/index.d.ts +7 -0
  4. package/dist/client/index.js +17 -0
  5. package/dist/client/index.js.map +1 -0
  6. package/dist/client/rest-api-client.d.ts +20 -0
  7. package/dist/client/rest-api-client.js +310 -0
  8. package/dist/client/rest-api-client.js.map +1 -0
  9. package/dist/client/types/client.d.ts +22 -0
  10. package/dist/client/types/client.js +2 -0
  11. package/dist/client/types/client.js.map +1 -0
  12. package/dist/config/client.d.ts +3 -0
  13. package/dist/config/client.js +120 -0
  14. package/dist/config/client.js.map +1 -0
  15. package/dist/config/file.d.ts +6 -0
  16. package/dist/config/file.js +19 -0
  17. package/dist/config/file.js.map +1 -0
  18. package/dist/config/index.d.ts +6 -0
  19. package/dist/config/index.js +45 -0
  20. package/dist/config/index.js.map +1 -0
  21. package/dist/config/mcp-server.d.ts +6 -0
  22. package/dist/config/mcp-server.js +14 -0
  23. package/dist/config/mcp-server.js.map +1 -0
  24. package/dist/config/tool-condition.d.ts +3 -0
  25. package/dist/config/tool-condition.js +53 -0
  26. package/dist/config/tool-condition.js.map +1 -0
  27. package/dist/index.d.ts +2 -0
  28. package/dist/index.js +123 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/schema/contelligence/index.d.ts +11 -0
  31. package/dist/schema/contelligence/index.js +24 -0
  32. package/dist/schema/contelligence/index.js.map +1 -0
  33. package/dist/schema/definition/field.d.ts +14 -0
  34. package/dist/schema/definition/field.js +27 -0
  35. package/dist/schema/definition/field.js.map +1 -0
  36. package/dist/schema/definition/index.d.ts +98 -0
  37. package/dist/schema/definition/index.js +101 -0
  38. package/dist/schema/definition/index.js.map +1 -0
  39. package/dist/schema/definition/layout.d.ts +10 -0
  40. package/dist/schema/definition/layout.js +22 -0
  41. package/dist/schema/definition/layout.js.map +1 -0
  42. package/dist/schema/media/index.d.ts +8 -0
  43. package/dist/schema/media/index.js +11 -0
  44. package/dist/schema/media/index.js.map +1 -0
  45. package/dist/schema/report/detail.d.ts +5 -0
  46. package/dist/schema/report/detail.js +18 -0
  47. package/dist/schema/report/detail.js.map +1 -0
  48. package/dist/schema/shared/detail-info.d.ts +423 -0
  49. package/dist/schema/shared/detail-info.js +153 -0
  50. package/dist/schema/shared/detail-info.js.map +1 -0
  51. package/dist/schema/user/index.d.ts +74 -0
  52. package/dist/schema/user/index.js +54 -0
  53. package/dist/schema/user/index.js.map +1 -0
  54. package/dist/server/index.d.ts +4 -0
  55. package/dist/server/index.js +66 -0
  56. package/dist/server/index.js.map +1 -0
  57. package/dist/server/tool-filters.d.ts +7 -0
  58. package/dist/server/tool-filters.js +17 -0
  59. package/dist/server/tool-filters.js.map +1 -0
  60. package/dist/server/types/server.d.ts +15 -0
  61. package/dist/server/types/server.js +2 -0
  62. package/dist/server/types/server.js.map +1 -0
  63. package/dist/tools/categories.d.ts +14 -0
  64. package/dist/tools/categories.js +13 -0
  65. package/dist/tools/categories.js.map +1 -0
  66. package/dist/tools/factory.d.ts +150 -0
  67. package/dist/tools/factory.js +9 -0
  68. package/dist/tools/factory.js.map +1 -0
  69. package/dist/tools/index.d.ts +4 -0
  70. package/dist/tools/index.js +25 -0
  71. package/dist/tools/index.js.map +1 -0
  72. package/dist/tools/ireporter/contelligence/get-cluster-value.d.ts +31 -0
  73. package/dist/tools/ireporter/contelligence/get-cluster-value.js +92 -0
  74. package/dist/tools/ireporter/contelligence/get-cluster-value.js.map +1 -0
  75. package/dist/tools/ireporter/contelligence/get-records.d.ts +138 -0
  76. package/dist/tools/ireporter/contelligence/get-records.js +234 -0
  77. package/dist/tools/ireporter/contelligence/get-records.js.map +1 -0
  78. package/dist/tools/ireporter/contelligence/get-report-detail.d.ts +161 -0
  79. package/dist/tools/ireporter/contelligence/get-report-detail.js +177 -0
  80. package/dist/tools/ireporter/contelligence/get-report-detail.js.map +1 -0
  81. package/dist/tools/ireporter/definition/get-definition.d.ts +156 -0
  82. package/dist/tools/ireporter/definition/get-definition.js +147 -0
  83. package/dist/tools/ireporter/definition/get-definition.js.map +1 -0
  84. package/dist/tools/ireporter/definition/get-definitions.d.ts +120 -0
  85. package/dist/tools/ireporter/definition/get-definitions.js +174 -0
  86. package/dist/tools/ireporter/definition/get-definitions.js.map +1 -0
  87. package/dist/tools/ireporter/license/get-license.d.ts +64 -0
  88. package/dist/tools/ireporter/license/get-license.js +105 -0
  89. package/dist/tools/ireporter/license/get-license.js.map +1 -0
  90. package/dist/tools/ireporter/media/download-file.d.ts +30 -0
  91. package/dist/tools/ireporter/media/download-file.js +71 -0
  92. package/dist/tools/ireporter/media/download-file.js.map +1 -0
  93. package/dist/tools/ireporter/media/list-media.d.ts +37 -0
  94. package/dist/tools/ireporter/media/list-media.js +100 -0
  95. package/dist/tools/ireporter/media/list-media.js.map +1 -0
  96. package/dist/tools/ireporter/user/get-user.d.ts +35 -0
  97. package/dist/tools/ireporter/user/get-user.js +77 -0
  98. package/dist/tools/ireporter/user/get-user.js.map +1 -0
  99. package/dist/tools/ireporter/user/get-users.d.ts +57 -0
  100. package/dist/tools/ireporter/user/get-users.js +91 -0
  101. package/dist/tools/ireporter/user/get-users.js.map +1 -0
  102. package/dist/tools/types/tool.d.ts +22 -0
  103. package/dist/tools/types/tool.js +2 -0
  104. package/dist/tools/types/tool.js.map +1 -0
  105. package/dist/utils/attachment.d.ts +25 -0
  106. package/dist/utils/attachment.js +47 -0
  107. package/dist/utils/attachment.js.map +1 -0
  108. package/dist/utils/coerce.d.ts +5 -0
  109. package/dist/utils/coerce.js +42 -0
  110. package/dist/utils/coerce.js.map +1 -0
  111. package/dist/utils/error.d.ts +27 -0
  112. package/dist/utils/error.js +43 -0
  113. package/dist/utils/error.js.map +1 -0
  114. package/dist/utils/file.d.ts +1 -0
  115. package/dist/utils/file.js +5 -0
  116. package/dist/utils/file.js.map +1 -0
  117. package/dist/utils/logger.d.ts +14 -0
  118. package/dist/utils/logger.js +103 -0
  119. package/dist/utils/logger.js.map +1 -0
  120. package/dist/utils/pagination.d.ts +35 -0
  121. package/dist/utils/pagination.js +52 -0
  122. package/dist/utils/pagination.js.map +1 -0
  123. package/dist/utils/validator.d.ts +2 -0
  124. package/dist/utils/validator.js +16 -0
  125. package/dist/utils/validator.js.map +1 -0
  126. package/dist/utils/xml.d.ts +4 -0
  127. package/dist/utils/xml.js +18 -0
  128. package/dist/utils/xml.js.map +1 -0
  129. package/package.json +77 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Cimtops
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,265 @@
1
+ # i-Reporter MCP Server
2
+
3
+ ConMas i-Reporter Web APIをAIアシスタント(Claude Desktop、Claude Code等)に公開する [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) サーバーです。stdioトランスポートで動作し、帳票定義の検索・レコード照会・ファイルエクスポートなど取得系APIをツールとして提供します。
4
+
5
+ ## 機能概要
6
+
7
+ - セッションベース認証(Login / Logout)を自動管理
8
+ - 10個の読み取り専用ツールを提供(定義、帳票、ユーザー、ライセンス、メディア)
9
+ - ページネーション対応(デフォルト50件、最大500件)
10
+ - ツールフィルタリング(カテゴリ・ツール名で有効/無効を制御)
11
+ - 構造化レスポンス(structuredContent)とテキストレスポンスの両方を返却
12
+ - プロキシ・相互TLS対応
13
+
14
+ ## 要件
15
+
16
+ - **Node.js** 22以上
17
+ - **pnpm** 10.15以上
18
+ - 有効な **i-Reporter認証情報**(ユーザーID、パスワード、必要に応じて会社ID)
19
+
20
+ ## クイックスタート
21
+
22
+ ### npx で即時実行(インストール不要)
23
+
24
+ ```bash
25
+ npx --yes @ireporter/mcp-server@latest -- \
26
+ --base-url https://your-host/ \
27
+ --user your_user \
28
+ --password your_password
29
+ ```
30
+
31
+ 最初の `--` は npx からMCPサーバーへフラグを転送するために必要です。
32
+
33
+ ### ローカルインストール
34
+
35
+ ```bash
36
+ git clone <repository-url>
37
+ cd i-reporter-mcp
38
+ pnpm install
39
+ pnpm build
40
+ pnpm start -- --base-url https://your-host/ --user your_user --password your_password
41
+ ```
42
+
43
+ ## 設定
44
+
45
+ すべての設定はCLIフラグまたは環境変数で提供できます。CLIフラグは `--kebab-case`、環境変数は `SCREAMING_SNAKE_CASE` を使用します。
46
+
47
+ ### 認証(必須)
48
+
49
+ | 環境変数 | CLIフラグ | 説明 |
50
+ |----------|----------|------|
51
+ | `IREPORTER_BASE_URL` | `--base-url` | i-Reporterサーバーの基底URL(例: `https://example.com/ConMasAPIDEVSNEW/`)。完全なAPI URL(`…/APIExecute.aspx`)を指定した場合は自動で分離されます。 |
52
+ | `IREPORTER_USER_ID` | `--user` | ログイン用ユーザーID。`IREPORTER_USERNAME` も利用可。 |
53
+ | `IREPORTER_PASSWORD` | `--password` | パスワード。 |
54
+ | `IREPORTER_COMPANY_ID` | `--company-id` | 会社ID(マルチテナント環境で必要)。 |
55
+
56
+ ### API接続
57
+
58
+ | 環境変数 | CLIフラグ | デフォルト | 説明 |
59
+ |----------|----------|-----------|------|
60
+ | `IREPORTER_API_PATH` | `--api-path` | `ConMasAPI/Rests/APIExecute.aspx` | ベースURLに連結する相対パス。base-urlに完全URLを指定した場合は不要。 |
61
+ | `IREPORTER_TIMEOUT_MS` | `--timeout` | `30000` | リクエストタイムアウト(ミリ秒)。 |
62
+ | `IREPORTER_USER_AGENT` | `--user-agent` | - | カスタムUser-Agentヘッダー。 |
63
+ | `IREPORTER_LOCALE` | `--locale` | - | APIに転送するロケール文字列。 |
64
+
65
+ ### ネットワーク / TLS
66
+
67
+ | 環境変数 | CLIフラグ | 説明 |
68
+ |----------|----------|------|
69
+ | `HTTPS_PROXY` | `--https-proxy` | HTTPSプロキシURL(例: `http://proxy.local:8080`)。 |
70
+ | `IREPORTER_CLIENT_CERT_PATH` | `--client-cert` | 相互TLS用PFXクライアント証明書のパス。 |
71
+ | `IREPORTER_CLIENT_CERT_PASSPHRASE` | `--client-cert-passphrase` | PFXファイルのパスフレーズ。 |
72
+
73
+ ### ファイル処理
74
+
75
+ | 環境変数 | CLIフラグ | 説明 |
76
+ |----------|----------|------|
77
+ | `IREPORTER_ATTACHMENTS_DIR` | `--attachments-dir` | ダウンロードファイルの保存先ディレクトリ。未指定時はOSの一時ディレクトリ内に自動作成。 |
78
+
79
+ ### ツールフィルタリング
80
+
81
+ | 環境変数 | CLIフラグ | 説明 |
82
+ |----------|----------|------|
83
+ | `IREPORTER_ENABLED_CATEGORIES` | `--enabled-categories` | 有効にするツールカテゴリのカンマ/スペース区切りリスト。 |
84
+ | `IREPORTER_INCLUDE_TOOLS` | `--include-tools` | 登録するツール名の許可リスト。 |
85
+ | `IREPORTER_EXCLUDE_TOOLS` | `--exclude-tools` | 除外するツール名のブロックリスト。 |
86
+
87
+ カテゴリ: `license`, `definition`, `contelligence`, `user`, `media`
88
+
89
+ ### MCPサーバーメタデータ
90
+
91
+ | 環境変数 | CLIフラグ | 説明 |
92
+ |----------|----------|------|
93
+ | `MCP_SERVER_NAME` | `--name` | サーバー名のオーバーライド。 |
94
+ | `MCP_SERVER_VERSION` | `--version` | バージョンのオーバーライド。 |
95
+
96
+ ## ツール一覧
97
+
98
+ ### 定義 (definition)
99
+
100
+ | ツール名 | 説明 | 主な引数 |
101
+ |---------|------|---------|
102
+ | `ireporter-get-definitions` | フォーム定義(ラベル/シート/セット/ブック)を検索・一覧取得 | `keyword`, `labelId`, `publicStatus`, `limit`, `offset` |
103
+ | `ireporter-get-definition` | 単一定義の詳細を取得(備考、ラベル、クラスター構造) | `topId` (必須) |
104
+
105
+ ### 帳票 (contelligence)
106
+
107
+ | ツール名 | 説明 | 主な引数 |
108
+ |---------|------|---------|
109
+ | `ireporter-get-records` | 提出済み帳票レコードを検索・一覧取得 | `keyword`, `editStatus`, `definitionIds`, `limit`, `offset` |
110
+ | `ireporter-get-report-detail` | 単一帳票の詳細(備考、クラスター値、承認情報) | `topId` または `defTopId` / `systemKey1-5` |
111
+ | `ireporter-get-cluster-value` | 帳票内の単一クラスター(セル)値を取得 | `reportId`, `sheetNo`, `clusterSearchMode`, `clusterSearchValue` |
112
+
113
+ ### ユーザー (user)
114
+
115
+ | ツール名 | 説明 | 主な引数 |
116
+ |---------|------|---------|
117
+ | `ireporter-get-users` | ユーザー一覧を取得(名前、メール、機能フラグ) | `limit`, `offset`, `withSignature` |
118
+ | `ireporter-get-user` | 単一ユーザーの詳細を取得 | `userId` (必須) |
119
+
120
+ ### ライセンス (license)
121
+
122
+ | ツール名 | 説明 | 主な引数 |
123
+ |---------|------|---------|
124
+ | `ireporter-get-license` | ライセンス利用状況のサマリー(総数/有効/期限切れ/機能別) | `limit`, `offset` |
125
+
126
+ ### メディア (media)
127
+
128
+ | ツール名 | 説明 | 主な引数 |
129
+ |---------|------|---------|
130
+ | `ireporter-list-media` | 帳票のダウンロード可能な形式を確認 | `topId` または `defTopId` / `systemKey1-5` |
131
+ | `ireporter-download-file` | 帳票をPDF/レイヤー付きPDF/Excelでエクスポート | `reportId`, `fileType` |
132
+
133
+ ### 典型的なワークフロー
134
+
135
+ ```
136
+ 1. ireporter-get-definitions -- フォーム定義を検索
137
+ 2. ireporter-get-records -- 定義IDで帳票レコードを検索
138
+ 3. ireporter-get-report-detail -- レコードの詳細を確認
139
+ 4. ireporter-download-file -- PDF/Excelでエクスポート
140
+ ```
141
+
142
+ ## 開発スクリプト
143
+
144
+ | コマンド | 説明 |
145
+ |---------|------|
146
+ | `pnpm dev` | ウォッチモードで起動(tsx)。デバッグログ有効。 |
147
+ | `pnpm build` | TypeScriptを `dist/` にコンパイル。 |
148
+ | `pnpm start` | コンパイル済みサーバーを起動。 |
149
+ | `pnpm test` | テスト実行(vitest)。 |
150
+ | `pnpm lint` | ESLint + Prettier + 型チェック。 |
151
+ | `pnpm inspector` | MCP Inspectorで接続テスト。 |
152
+
153
+ ## Claude Desktop統合
154
+
155
+ `~/.claude/config/claude_desktop_config.json` に追加:
156
+
157
+ ```json
158
+ {
159
+ "mcpServers": {
160
+ "ireporter": {
161
+ "type": "stdio",
162
+ "command": "pnpm",
163
+ "args": [
164
+ "--dir",
165
+ "/path/to/i-reporter-mcp-server",
166
+ "start",
167
+ "--",
168
+ "--base-url",
169
+ "https://your-host",
170
+ "--user",
171
+ "your_user",
172
+ "--password",
173
+ "your_password"
174
+ ],
175
+ "env": {
176
+ "IREPORTER_ATTACHMENTS_DIR": "/tmp/ireporter"
177
+ }
178
+ }
179
+ }
180
+ }
181
+ ```
182
+
183
+ ### npx を使う場合
184
+
185
+ ```json
186
+ {
187
+ "mcpServers": {
188
+ "ireporter": {
189
+ "type": "stdio",
190
+ "command": "npx",
191
+ "args": [
192
+ "--yes",
193
+ "@ireporter/mcp-server@latest",
194
+ "--",
195
+ "--base-url",
196
+ "https://your-host",
197
+ "--user",
198
+ "your_user",
199
+ "--password",
200
+ "your_password"
201
+ ]
202
+ }
203
+ }
204
+ }
205
+ ```
206
+
207
+ ### .env ファイルの利用
208
+
209
+ リポジトリ直下に `.env` を配置すると自動で読み込まれます(`pnpm dev` / `pnpm start` いずれも対応)。
210
+
211
+ ```bash
212
+ # .env
213
+ IREPORTER_BASE_URL=https://your-host
214
+ IREPORTER_USER_ID=your_user
215
+ IREPORTER_PASSWORD=your_password
216
+ IREPORTER_ATTACHMENTS_DIR=/tmp/ireporter
217
+ ```
218
+
219
+ ## トラブルシューティング
220
+
221
+ ### 認証エラー
222
+
223
+ - **症状**: XMLレスポンスでエラーコード `1` が返る
224
+ - **対処**: `IREPORTER_BASE_URL`, `IREPORTER_USER_ID`, `IREPORTER_PASSWORD` を確認。マルチテナント環境では `IREPORTER_COMPANY_ID` (または `--company-id`) が必要です。
225
+
226
+ ### ベースURLの指定
227
+
228
+ - `IREPORTER_BASE_URL` にはREST APIの手前までのURLを指定します(例: `https://example.com/ConMasAPIDEVSNEW/`)。
229
+ - `…/APIExecute.aspx` まで含めた完全URLを指定した場合も自動でパスを分離するため動作します。
230
+ - 末尾のスラッシュは有無どちらでも可。
231
+
232
+ ### Claude DesktopでJSONパースエラーが出る
233
+
234
+ - pnpmの実行時バナー出力がMCPクライアントに送られることが原因です。
235
+ - 本リポジトリでは `.npmrc` で `reporter=silent` を指定済みです。
236
+ - 通常のログを見たい場合は `pnpm --reporter=default <command>` で一時的に上書きしてください。
237
+
238
+ ### デバッグログ
239
+
240
+ - `IREPORTER_LOG_LEVEL=debug` を設定すると、リクエスト/レスポンスの詳細が出力されます。
241
+ - `pnpm dev` はデフォルトでデバッグログが有効です。
242
+
243
+ ### ダウンロードしたファイルが見つからない
244
+
245
+ - `IREPORTER_ATTACHMENTS_DIR` を明示的に設定して保存先を固定してください。
246
+ - 未設定の場合はOSの一時ディレクトリ配下 (`os.tmpdir()/ireporter-mcp-attachments/`) に保存されます。
247
+
248
+ ### prompts.list / resources.list のエラー
249
+
250
+ - MCP初期化時にClaude が呼び出す `prompts.list` と `resources.list` には、`ireporter-help` プロンプトと `ireporter-readme` リソースが応答するためエラーは発生しません。
251
+
252
+ ### セッションのクリーンアップ
253
+
254
+ - サーバーは `SIGINT` / `SIGTERM` / `beforeExit` 時に自動で Logout APIを呼び出し、セッションを破棄します。
255
+
256
+ ## ロードマップ
257
+
258
+ - レコードCRUDフロー(AutoGenerate / UpdateReport / DeleteReport、CSV/ZIPアップロード対応)
259
+ - メディアアップロード/削除APIの調査と対応
260
+ - 自動テストとCI設定
261
+ - DockerイメージとMCPパッケージの公開
262
+
263
+ ## ライセンス
264
+
265
+ MIT
@@ -0,0 +1,7 @@
1
+ import type { IReporterClientConfig } from "./types/client.js";
2
+ import { IReporterRestClient } from "./rest-api-client.js";
3
+ export type { IReporterClientConfig };
4
+ export type { IReporterRestClient } from "./rest-api-client.js";
5
+ export declare const getIReporterClient: (config: IReporterClientConfig) => IReporterRestClient;
6
+ export declare const getActiveClient: () => IReporterRestClient | null;
7
+ export declare const logoutClient: () => Promise<void>;
@@ -0,0 +1,17 @@
1
+ import { IReporterRestClient } from "./rest-api-client.js";
2
+ let client = null;
3
+ export const getIReporterClient = (config) => {
4
+ if (client) {
5
+ return client;
6
+ }
7
+ client = new IReporterRestClient(config);
8
+ return client;
9
+ };
10
+ export const getActiveClient = () => client;
11
+ export const logoutClient = async () => {
12
+ if (!client) {
13
+ return;
14
+ }
15
+ await client.logout();
16
+ };
17
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAE3D,IAAI,MAAM,GAA+B,IAAI,CAAC;AAK9C,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAChC,MAA6B,EACR,EAAE;IACvB,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,MAAM,GAAG,IAAI,mBAAmB,CAAC,MAAM,CAAC,CAAC;IACzC,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG,GAA+B,EAAE,CAAC,MAAM,CAAC;AAExE,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,IAAmB,EAAE;IACpD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO;IACT,CAAC;IACD,MAAM,MAAM,CAAC,MAAM,EAAE,CAAC;AACxB,CAAC,CAAC"}
@@ -0,0 +1,20 @@
1
+ import type { IReporterClientConfig, IReporterCommandParams, IReporterFileDownload } from "./types/client.js";
2
+ export declare class IReporterRestClient {
3
+ private readonly config;
4
+ private readonly http;
5
+ private readonly parser;
6
+ private session;
7
+ private cookie;
8
+ private readonly apiPath;
9
+ constructor(config: IReporterClientConfig);
10
+ login(): Promise<void>;
11
+ logout(): Promise<void>;
12
+ executeCommand<T = unknown>(command: string, params?: IReporterCommandParams): Promise<T>;
13
+ downloadFile(command: string, params?: IReporterCommandParams): Promise<IReporterFileDownload>;
14
+ private executeRequest;
15
+ private executeBinaryRequest;
16
+ private buildCookieHeader;
17
+ private captureCookies;
18
+ private parseXml;
19
+ private assertNoError;
20
+ }
@@ -0,0 +1,310 @@
1
+ import { readFileSync } from "fs";
2
+ import axios from "axios";
3
+ import { Agent } from "https";
4
+ import { HttpsProxyAgent } from "https-proxy-agent";
5
+ import { XMLParser } from "fast-xml-parser";
6
+ import { ErrorCode, IReporterMCPError, isIReporterMCPError } from "../utils/error.js";
7
+ import { logger } from "../utils/logger.js";
8
+ export class IReporterRestClient {
9
+ config;
10
+ http;
11
+ parser = new XMLParser({
12
+ ignoreAttributes: false,
13
+ attributeNamePrefix: "",
14
+ parseAttributeValue: true,
15
+ processEntities: false,
16
+ });
17
+ session = null;
18
+ cookie = null;
19
+ apiPath;
20
+ constructor(config) {
21
+ this.config = config;
22
+ this.http = axios.create({
23
+ baseURL: config.baseUrl,
24
+ timeout: config.requestTimeoutMs,
25
+ headers: {
26
+ "User-Agent": config.userAgent ?? "i-reporter-mcp-server",
27
+ Accept: "application/xml, text/xml, */*;q=0.8",
28
+ },
29
+ httpsAgent: buildHttpsAgent(config),
30
+ proxy: false,
31
+ });
32
+ this.apiPath = config.apiPath.replace(/^\/+/, "");
33
+ }
34
+ async login() {
35
+ if (this.session) {
36
+ return;
37
+ }
38
+ const params = new URLSearchParams({
39
+ command: "Login",
40
+ user: this.config.userId,
41
+ password: this.config.password,
42
+ });
43
+ const response = await this.executeRequest(params, {
44
+ expectLoginResponse: true,
45
+ });
46
+ const loginResult = response?.conmas?.loginResult;
47
+ if (!loginResult) {
48
+ throw new IReporterMCPError(ErrorCode.AUTH_FAILED, "i-Reporter login response was missing", response);
49
+ }
50
+ const code = `${loginResult.code ?? ""}`;
51
+ if (code !== "0") {
52
+ throw new IReporterMCPError(ErrorCode.AUTH_FAILED, loginResult.remark ?? "i-Reporter login failed", loginResult);
53
+ }
54
+ this.session = {
55
+ sessionId: extractSessionId(this.cookie),
56
+ };
57
+ logger.info("Logged into i-Reporter API");
58
+ }
59
+ async logout() {
60
+ try {
61
+ const params = new URLSearchParams({ command: "Logout" });
62
+ await this.executeRequest(params, { ignoreErrors: true });
63
+ }
64
+ catch (error) {
65
+ logger.warn("Failed to logout from i-Reporter", {
66
+ component: "rest-api-client",
67
+ operation: "logout"
68
+ }, error);
69
+ }
70
+ finally {
71
+ this.session = null;
72
+ this.cookie = null;
73
+ }
74
+ }
75
+ async executeCommand(command, params = {}) {
76
+ await this.login();
77
+ const searchParams = new URLSearchParams({ command });
78
+ for (const [key, value] of Object.entries(params)) {
79
+ if (value === undefined || value === null) {
80
+ continue;
81
+ }
82
+ searchParams.append(key, String(value));
83
+ }
84
+ const response = await this.executeRequest(searchParams);
85
+ return response;
86
+ }
87
+ async downloadFile(command, params = {}) {
88
+ await this.login();
89
+ const searchParams = new URLSearchParams({ command });
90
+ for (const [key, value] of Object.entries(params)) {
91
+ if (value !== undefined && value !== null) {
92
+ searchParams.append(key, String(value));
93
+ }
94
+ }
95
+ return await this.executeBinaryRequest(searchParams);
96
+ }
97
+ async executeRequest(params, options) {
98
+ try {
99
+ const response = await this.http.post(this.apiPath, params.toString(), {
100
+ headers: {
101
+ "Content-Type": "application/x-www-form-urlencoded",
102
+ ...this.buildCookieHeader(),
103
+ },
104
+ responseType: "text",
105
+ });
106
+ this.captureCookies(response.headers);
107
+ const payload = this.parseXml(response.data);
108
+ if (options?.expectLoginResponse) {
109
+ return payload;
110
+ }
111
+ if (!options?.ignoreErrors) {
112
+ this.assertNoError(payload);
113
+ }
114
+ return payload;
115
+ }
116
+ catch (error) {
117
+ if (error instanceof IReporterMCPError) {
118
+ throw error;
119
+ }
120
+ throw new IReporterMCPError(ErrorCode.API_ERROR, "Failed to execute i-Reporter API request", normalizeError(error));
121
+ }
122
+ }
123
+ async executeBinaryRequest(params) {
124
+ try {
125
+ const response = await this.http.post(this.apiPath, params.toString(), {
126
+ headers: {
127
+ "Content-Type": "application/x-www-form-urlencoded",
128
+ ...this.buildCookieHeader(),
129
+ },
130
+ responseType: "arraybuffer",
131
+ });
132
+ this.captureCookies(response.headers);
133
+ const contentType = (response.headers["content-type"] ?? "");
134
+ if (contentType.includes("text/xml") || contentType.includes("application/xml")) {
135
+ const text = Buffer.from(response.data).toString("utf-8");
136
+ const payload = this.parseXml(text);
137
+ this.assertNoError(payload);
138
+ throw new IReporterMCPError(ErrorCode.API_ERROR, "Expected file payload but received XML response", payload);
139
+ }
140
+ // Check if response is actually an error message disguised as a file
141
+ if (response.data.byteLength < 1000) {
142
+ const text = Buffer.from(response.data).toString("utf-8");
143
+ if (text.includes("<?xml") || text.includes("<conmas>")) {
144
+ try {
145
+ const payload = this.parseXml(text);
146
+ this.assertNoError(payload);
147
+ throw new IReporterMCPError(ErrorCode.API_ERROR, "Expected file payload but received XML response", payload);
148
+ }
149
+ catch (error) {
150
+ if (error instanceof IReporterMCPError) {
151
+ throw error;
152
+ }
153
+ throw new IReporterMCPError(ErrorCode.API_ERROR, "Expected file payload but received XML response", { responseText: text.substring(0, 500) });
154
+ }
155
+ }
156
+ }
157
+ return {
158
+ filename: extractFilename(response.headers["content-disposition"]),
159
+ mimeType: contentType || "application/octet-stream",
160
+ data: response.data,
161
+ };
162
+ }
163
+ catch (error) {
164
+ if (error instanceof IReporterMCPError) {
165
+ throw error;
166
+ }
167
+ throw new IReporterMCPError(ErrorCode.API_ERROR, "Failed to download i-Reporter file", normalizeError(error));
168
+ }
169
+ }
170
+ buildCookieHeader() {
171
+ if (!this.cookie) {
172
+ return {};
173
+ }
174
+ return { Cookie: this.cookie };
175
+ }
176
+ captureCookies(headers) {
177
+ const setCookie = headers["set-cookie"];
178
+ if (!setCookie) {
179
+ return;
180
+ }
181
+ const rawCookies = Array.isArray(setCookie)
182
+ ? setCookie
183
+ : typeof setCookie === "string"
184
+ ? [setCookie]
185
+ : [];
186
+ if (!rawCookies.length) {
187
+ return;
188
+ }
189
+ this.cookie = rawCookies
190
+ .map((cookie) => cookie.split(";")[0]?.trim())
191
+ .filter(Boolean)
192
+ .join("; ");
193
+ }
194
+ parseXml(xml) {
195
+ try {
196
+ // XMLの基本的な検証
197
+ if (!xml || typeof xml !== 'string') {
198
+ throw new IReporterMCPError(ErrorCode.INVALID_XML_RESPONSE, "Empty or invalid XML response received", { xml: xml?.substring(0, 200) + '...' });
199
+ }
200
+ // XMLの開始タグをチェック
201
+ if (!xml.trim().startsWith('<')) {
202
+ throw new IReporterMCPError(ErrorCode.INVALID_XML_RESPONSE, "Response does not appear to be valid XML", { xml: xml.substring(0, 200) + '...' });
203
+ }
204
+ const parsed = this.parser.parse(xml);
205
+ // パース結果の基本検証
206
+ if (!parsed || typeof parsed !== 'object') {
207
+ throw new IReporterMCPError(ErrorCode.XML_PARSE_ERROR, "XML parsing resulted in invalid object", { xml: xml.substring(0, 200) + '...' });
208
+ }
209
+ return parsed;
210
+ }
211
+ catch (error) {
212
+ if (isIReporterMCPError(error)) {
213
+ throw error;
214
+ }
215
+ logger.error("XML parsing failed", {
216
+ component: "rest-api-client",
217
+ operation: "parseXml",
218
+ xmlLength: xml?.length || 0,
219
+ xmlPreview: xml?.substring(0, 200) + '...'
220
+ }, error);
221
+ throw new IReporterMCPError(ErrorCode.XML_PARSE_ERROR, "Failed to parse i-Reporter XML response", {
222
+ xmlLength: xml?.length || 0,
223
+ xmlPreview: xml?.substring(0, 200) + '...',
224
+ error: normalizeError(error),
225
+ });
226
+ }
227
+ }
228
+ assertNoError(payload) {
229
+ const errorNode = payload?.conmas?.error;
230
+ if (!errorNode) {
231
+ return;
232
+ }
233
+ const code = Number.parseInt(`${errorNode.code ?? 0}`, 10);
234
+ if (Number.isNaN(code) || code === 0) {
235
+ return;
236
+ }
237
+ const remarks = errorNode.remarks ?? errorNode.remark;
238
+ const message = Array.isArray(remarks)
239
+ ? remarks.map((item) => item.remark).join("; ")
240
+ : typeof remarks === "string"
241
+ ? remarks
242
+ : "i-Reporter API returned an error";
243
+ throw new IReporterMCPError(ErrorCode.API_ERROR, message, errorNode);
244
+ }
245
+ }
246
+ const buildHttpsAgent = (config) => {
247
+ const agentOptions = {};
248
+ if (config.pfxFilePath && config.pfxPassphrase) {
249
+ agentOptions.pfx = readFileSync(config.pfxFilePath);
250
+ agentOptions.passphrase = config.pfxPassphrase;
251
+ }
252
+ if (config.httpsProxy) {
253
+ return new HttpsProxyAgent(config.httpsProxy, agentOptions);
254
+ }
255
+ return new Agent(agentOptions);
256
+ };
257
+ const extractSessionId = (cookie) => {
258
+ if (!cookie) {
259
+ return "";
260
+ }
261
+ const match = cookie.match(/ASP\.NET_SessionId=([^;]+)/);
262
+ return match ? match[1] : "";
263
+ };
264
+ const extractFilename = (contentDisposition) => {
265
+ if (typeof contentDisposition !== "string") {
266
+ return "ireporter-download.bin";
267
+ }
268
+ let raw;
269
+ const match = contentDisposition.match(/filename\*=UTF-8''([^;]+)/);
270
+ if (match) {
271
+ try {
272
+ raw = decodeURIComponent(match[1]);
273
+ }
274
+ catch {
275
+ // Malformed URI encoding; ignore
276
+ }
277
+ }
278
+ if (!raw) {
279
+ const fallback = contentDisposition.match(/filename="?([^";]+)"?/);
280
+ if (fallback) {
281
+ raw = fallback[1];
282
+ }
283
+ }
284
+ if (!raw) {
285
+ return "ireporter-download.bin";
286
+ }
287
+ // Strip directory components and null bytes to prevent path traversal
288
+ const sanitized = raw.replace(/[\x00/\\]/g, "_").replace(/^\.+/, "_");
289
+ return sanitized || "ireporter-download.bin";
290
+ };
291
+ const normalizeError = (error) => {
292
+ if (axios.isAxiosError(error)) {
293
+ // Exclude config/request to avoid leaking credentials (e.g. password in POST body)
294
+ return {
295
+ name: error.name,
296
+ message: error.message,
297
+ status: error.response?.status,
298
+ statusText: error.response?.statusText,
299
+ code: error.code,
300
+ };
301
+ }
302
+ if (error instanceof Error) {
303
+ return {
304
+ name: error.name,
305
+ message: error.message,
306
+ };
307
+ }
308
+ return { message: String(error) };
309
+ };
310
+ //# sourceMappingURL=rest-api-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rest-api-client.js","sourceRoot":"","sources":["../../src/client/rest-api-client.ts"],"names":[],"mappings":"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"}