bizgate-mcp-server 0.1.0 → 0.3.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 +182 -101
- package/dist/bizgate-client.d.ts +49 -18
- package/dist/bizgate-client.js +100 -11
- package/dist/cache.d.ts +9 -0
- package/dist/cache.js +24 -0
- package/dist/index.js +60 -23
- package/dist/types.d.ts +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,161 +1,242 @@
|
|
|
1
1
|
# bizgate-mcp-server
|
|
2
2
|
|
|
3
|
-
BizGate API と Claude を接続する MCP サーバーです。
|
|
4
|
-
|
|
3
|
+
BizGate API と Claude Code を接続する MCP サーバーです。
|
|
4
|
+
Claude に話しかけるだけで、企業の担当者名・電話番号・住所・部署情報などを調べられます。
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
```
|
|
7
|
+
例:
|
|
8
|
+
「富士フイルムBIの営業担当者の名前と電話番号を教えて」
|
|
9
|
+
「株式会社エージェントの企業情報を調べて」
|
|
10
|
+
「アサヒペンのマーケティングタグを見せて」
|
|
11
|
+
「この会社の全情報を調べて、Excelに入れて」
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
### 仕組み
|
|
7
15
|
|
|
8
16
|
```
|
|
9
|
-
[ユーザー] → [Claude] ←── MCP
|
|
17
|
+
[ユーザー] → [Claude Code] ←── MCP ──→ [本サーバー] ──→ [BizGate API]
|
|
10
18
|
```
|
|
11
19
|
|
|
12
|
-
|
|
13
|
-
2. Claude が MCP プロトコル経由で本サーバーのツールを呼び出す
|
|
14
|
-
3. 本サーバーが BizGate API に問い合わせ → JSON レスポンスを解析
|
|
15
|
-
4. 構造化された情報を Claude に返却
|
|
16
|
-
5. Claude がユーザーに自然言語で回答(スプレッドシートへの入力も可能)
|
|
20
|
+
> 現在は **Claude Code 専用** です。Claude ウェブサイト(claude.ai)では使用できません。
|
|
17
21
|
|
|
18
|
-
|
|
22
|
+
---
|
|
19
23
|
|
|
20
|
-
|
|
21
|
-
|---------|------|--------|
|
|
22
|
-
| `bizgate__company_search` | 企業の基本情報(住所・電話・代表者・業種・資本金 等) | 1回(結果なしでも課金) |
|
|
23
|
-
| `bizgate__department_search` | 部署情報(部署名・住所・電話番号)最大500件 | 1回(データなしは課金なし) |
|
|
24
|
-
| `bizgate__marketing_tags` | マーケティングタグ(SNS・MA・サービス・活動) | 1回(データなしは課金なし) |
|
|
25
|
-
| `bizgate__keyman_search` | 人事情報(部署・役職・発令日)最大500件 | 1回(データなしは課金なし) |
|
|
26
|
-
| `bizgate__company_full` | 企業+部署+人事を一括取得 | 3回 |
|
|
27
|
-
| `bizgate__usage_status` | 本日の残りAPI回数を確認 | 0回 |
|
|
24
|
+
## できること
|
|
28
25
|
|
|
29
|
-
|
|
26
|
+
| 調べたいこと | 取得できる情報 |
|
|
27
|
+
|------------|-------------|
|
|
28
|
+
| 企業の基本情報 | 住所、代表電話、代表者名、業種、資本金、売上、従業員数、HP |
|
|
29
|
+
| 部署情報 | 部署名、部署の電話番号、部署の住所(最大500件) |
|
|
30
|
+
| 担当者情報 | **担当者の実名**、役職、電話番号、住所、発令日 |
|
|
31
|
+
| マーケティングタグ | SNS導入、MAツール、事業サービス、採用情報、活動状況 |
|
|
32
|
+
| 一括取得 | 上記すべてをまとめて取得 |
|
|
30
33
|
|
|
31
|
-
|
|
34
|
+
---
|
|
32
35
|
|
|
33
|
-
|
|
34
|
-
- Claude Code がインストール済み
|
|
35
|
-
- BizGate API のアカウント(ユーザー名・パスワード・サービスキー)
|
|
36
|
+
## セットアップ(所要時間:約10分)
|
|
36
37
|
|
|
37
|
-
###
|
|
38
|
+
### 事前に必要なもの
|
|
38
39
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
40
|
+
- **Claude Code** がパソコンにインストール済み
|
|
41
|
+
- **Node.js 18 以上** がインストール済み
|
|
42
|
+
- **BizGate のアカウント情報**(管理者から受け取ってください)
|
|
43
|
+
- ユーザー名
|
|
44
|
+
- パスワード
|
|
45
|
+
- サービスキー(企業用・部署用は必須、マーケ・キーマン用は任意)
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
### ステップ 1:ターミナルを開く
|
|
50
|
+
|
|
51
|
+
Mac の場合:
|
|
52
|
+
1. `Command + Space` で Spotlight を開く
|
|
53
|
+
2. 「ターミナル」と入力して Enter
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
### ステップ 2:MCP サーバーを登録する
|
|
58
|
+
|
|
59
|
+
ターミナルに以下を **そのままコピーして貼り付け** → Enter を押してください。
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
claude mcp add --scope user bizgate -- npx bizgate-mcp-server
|
|
44
63
|
```
|
|
45
64
|
|
|
46
|
-
|
|
65
|
+
以下のように表示されれば OK です。
|
|
66
|
+
```
|
|
67
|
+
Added stdio MCP server bizgate...
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
### ステップ 3:設定ファイルを編集する
|
|
47
73
|
|
|
48
|
-
|
|
74
|
+
ターミナルに以下を **そのままコピーして貼り付け** → Enter を押してください。
|
|
49
75
|
|
|
50
|
-
```
|
|
51
|
-
claude
|
|
52
|
-
--transport stdio \
|
|
53
|
-
-- node /path/to/bizgate-mcp-server/dist/index.js
|
|
76
|
+
```
|
|
77
|
+
open ~/.claude.json
|
|
54
78
|
```
|
|
55
79
|
|
|
56
|
-
|
|
80
|
+
テキストエディタで設定ファイルが開きます。
|
|
57
81
|
|
|
58
|
-
|
|
82
|
+
ファイルの中から `"bizgate"` というセクションを探してください。
|
|
83
|
+
以下のように **書き換え** ます。
|
|
59
84
|
|
|
60
|
-
|
|
85
|
+
#### 書き換え前
|
|
61
86
|
|
|
62
87
|
```json
|
|
63
|
-
{
|
|
64
|
-
"
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
88
|
+
"bizgate": {
|
|
89
|
+
"type": "stdio",
|
|
90
|
+
"command": "npx",
|
|
91
|
+
"args": ["bizgate-mcp-server"],
|
|
92
|
+
"env": {}
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
#### 書き換え後
|
|
97
|
+
|
|
98
|
+
```json
|
|
99
|
+
"bizgate": {
|
|
100
|
+
"type": "stdio",
|
|
101
|
+
"command": "npx",
|
|
102
|
+
"args": ["bizgate-mcp-server"],
|
|
103
|
+
"env": {
|
|
104
|
+
"BIZGATE_USERNAME": "ここにユーザー名を入力",
|
|
105
|
+
"BIZGATE_PASSWORD": "ここにパスワードを入力",
|
|
106
|
+
"BIZGATE_AUTH_MODE": "basic",
|
|
107
|
+
"BIZGATE_DAILY_LIMIT": "200",
|
|
108
|
+
"BIZGATE_SKEY_COMPANY": "ここに企業APIキーを入力",
|
|
109
|
+
"BIZGATE_SKEY_DEPARTMENT": "ここに部署APIキーを入力",
|
|
110
|
+
"BIZGATE_SKEY_MARKETING": "ここにマーケAPIキーを入力",
|
|
111
|
+
"BIZGATE_SKEY_KEYMAN": "ここにキーマン(人名なし)APIキーを入力",
|
|
112
|
+
"BIZGATE_SKEY_KEYMAN_NAME": "ここにキーマン(人名あり)APIキーを入力"
|
|
80
113
|
}
|
|
81
114
|
}
|
|
82
115
|
```
|
|
83
116
|
|
|
84
|
-
>
|
|
117
|
+
> **注意(よくあるミス)**
|
|
118
|
+
> - `ここに〇〇を入力` の部分を、管理者から受け取った **実際の値** に置き換えてください
|
|
119
|
+
> - ダブルクォーテーション `"` は **消さないで** ください
|
|
120
|
+
> - カンマ `,` の位置を **変えないで** ください
|
|
121
|
+
> - 最後の行(`"BIZGATE_SKEY_KEYMAN_NAME"` の行)の末尾には **カンマをつけないで** ください
|
|
122
|
+
> - 編集後、`Command + S` で保存 → ファイルを閉じる
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
### ステップ 4:Claude Code を再起動する
|
|
85
127
|
|
|
86
|
-
|
|
128
|
+
もし Claude Code が開いている場合は、一度閉じてください。
|
|
87
129
|
|
|
88
|
-
|
|
130
|
+
ターミナルで以下を実行してください。
|
|
131
|
+
|
|
132
|
+
```
|
|
89
133
|
claude
|
|
90
134
|
```
|
|
91
135
|
|
|
92
|
-
|
|
136
|
+
---
|
|
93
137
|
|
|
94
|
-
|
|
138
|
+
### ステップ 5:接続を確認する
|
|
95
139
|
|
|
96
|
-
Claude Code
|
|
97
|
-
|
|
98
|
-
### 基本的な使い方
|
|
140
|
+
Claude Code が起動したら、以下を入力してください。
|
|
99
141
|
|
|
100
142
|
```
|
|
101
|
-
|
|
143
|
+
/mcp
|
|
144
|
+
```
|
|
102
145
|
|
|
103
|
-
|
|
146
|
+
一覧が表示されます。 `bizgate` の横に **✔ connected** と表示されていれば成功です。
|
|
104
147
|
|
|
105
|
-
|
|
106
|
-
```
|
|
148
|
+
うまくいかない場合は、このページの一番下の「うまくいかないとき」を確認してください。
|
|
107
149
|
|
|
108
|
-
|
|
150
|
+
---
|
|
109
151
|
|
|
110
|
-
|
|
111
|
-
富士フイルムBIの東京都にある人事部を調べて
|
|
152
|
+
## 使い方
|
|
112
153
|
|
|
113
|
-
|
|
114
|
-
```
|
|
154
|
+
設定完了後は、Claude に **日本語で話しかけるだけ** です。特別なコマンドは不要です。
|
|
115
155
|
|
|
116
|
-
###
|
|
156
|
+
### よく使うパターン
|
|
117
157
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
158
|
+
| やりたいこと | Claude への聞き方 |
|
|
159
|
+
|------------|-----------------|
|
|
160
|
+
| 担当者の名前と電話番号 | 「○○の営業担当者の名前と電話番号を教えて」 |
|
|
161
|
+
| 会社の基本情報を知りたい | 「株式会社○○の企業情報を教えて」 |
|
|
162
|
+
| 電話番号を知りたい | 「○○の電話番号は?」 |
|
|
163
|
+
| 部署の一覧を見たい | 「○○の部署一覧を出して」 |
|
|
164
|
+
| 特定の部署を探したい | 「○○の人事部の連絡先を教えて」 |
|
|
165
|
+
| 採用活動をしている会社か確認 | 「○○のマーケティングタグを教えて」 |
|
|
166
|
+
| 全情報をまとめて見たい | 「○○の全情報を調べて」 |
|
|
167
|
+
| Excelに入力したい | 「○○の情報を調べてExcelに入れて」 |
|
|
122
168
|
|
|
123
|
-
###
|
|
169
|
+
### 注意点
|
|
124
170
|
|
|
125
|
-
|
|
126
|
-
|
|
171
|
+
- **会社名は正確に** 入力してください(例:「ソフバン」→ 「ソフトバンク株式会社」)
|
|
172
|
+
- 1日に使える回数は **200回** までです(残り回数は毎回表示されます)
|
|
173
|
+
- 企業検索は、結果が見つからなくても **1回分消費** されます
|
|
174
|
+
- 部署・マーケ・キーマン検索は、データが見つからなかった場合は **消費されません**
|
|
175
|
+
- 担当者検索は、**1名あたり1回分消費** されます(デフォルト上位10名)
|
|
127
176
|
|
|
128
|
-
|
|
129
|
-
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## 提供ツール(参考情報)
|
|
180
|
+
|
|
181
|
+
通常はツール名を意識する必要はありません。Claude が自動で適切なツールを選びます。
|
|
182
|
+
|
|
183
|
+
| ツール名 | 説明 | API消費 |
|
|
184
|
+
|---------|------|--------|
|
|
185
|
+
| `bizgate__company_search` | 企業の基本情報(住所・電話・代表者・業種・資本金 等) | 1回(結果なしでも課金) |
|
|
186
|
+
| `bizgate__department_search` | 部署情報(部署名・住所・電話番号)最大500件 | 1回(データなしは課金なし) |
|
|
187
|
+
| `bizgate__marketing_tags` | マーケティングタグ(SNS・MA・採用・活動) | 1回(データなしは課金なし) |
|
|
188
|
+
| `bizgate__keyman_search` | 担当者情報(実名・役職・電話番号・住所) | 1回 + 詳細取得N回 |
|
|
189
|
+
| `bizgate__company_full` | 企業+部署+キーマンを一括取得 | 3回〜 |
|
|
190
|
+
| `bizgate__usage_status` | 本日の残りAPI回数を確認 | 0回 |
|
|
191
|
+
|
|
192
|
+
---
|
|
130
193
|
|
|
131
|
-
##
|
|
194
|
+
## 環境変数一覧(参考情報)
|
|
132
195
|
|
|
133
196
|
| 変数名 | 必須 | 説明 |
|
|
134
197
|
|-------|------|------|
|
|
135
|
-
| `BIZGATE_USERNAME` |
|
|
136
|
-
| `BIZGATE_PASSWORD` |
|
|
198
|
+
| `BIZGATE_USERNAME` | ○ | BizGate ユーザー名 |
|
|
199
|
+
| `BIZGATE_PASSWORD` | ○ | BizGate パスワード |
|
|
137
200
|
| `BIZGATE_AUTH_MODE` | | `basic`(デフォルト)または `ip` |
|
|
138
|
-
| `BIZGATE_APP` | ○(IP
|
|
201
|
+
| `BIZGATE_APP` | ○(IP認証時のみ) | アプリ識別子 |
|
|
139
202
|
| `BIZGATE_SKEY_COMPANY` | ○ | 企業APIのサービスキー |
|
|
140
203
|
| `BIZGATE_SKEY_DEPARTMENT` | ○ | 部署APIのサービスキー |
|
|
141
204
|
| `BIZGATE_SKEY_MARKETING` | | マーケティングタグAPIのサービスキー |
|
|
142
|
-
| `BIZGATE_SKEY_KEYMAN` | |
|
|
205
|
+
| `BIZGATE_SKEY_KEYMAN` | | キーマン(人名なし)APIのサービスキー |
|
|
206
|
+
| `BIZGATE_SKEY_KEYMAN_NAME` | | キーマン(人名あり)APIのサービスキー |
|
|
143
207
|
| `BIZGATE_DAILY_LIMIT` | | 1日のAPI上限(デフォルト: 200) |
|
|
144
|
-
| `BIZGATE_BASE_URL` | | APIエンドポイント(通常変更不要) |
|
|
145
208
|
|
|
146
|
-
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
## うまくいかないとき
|
|
212
|
+
|
|
213
|
+
### `/mcp` で `bizgate` が `failed` になっている
|
|
214
|
+
|
|
215
|
+
ステップ 3 の設定ファイルに入力ミスがある可能性が高いです。以下を確認してください。
|
|
216
|
+
|
|
217
|
+
- ダブルクォーテーション `"` が抜けていないか
|
|
218
|
+
- カンマ `,` が余分についていないか(特に **最後の行の末尾**)
|
|
219
|
+
- ユーザー名・パスワード・サービスキーが正しいか
|
|
220
|
+
|
|
221
|
+
確認しても直らない場合は、管理者に `~/.claude.json` の中身を見せて相談してください。
|
|
222
|
+
|
|
223
|
+
### 「サービスキーが無効です」と表示される
|
|
224
|
+
|
|
225
|
+
サービスキーが間違っている、または有効期限切れです。管理者に確認してください。
|
|
226
|
+
|
|
227
|
+
### 「1日のリクエスト上限に達しました」と表示される
|
|
228
|
+
|
|
229
|
+
本日の利用回数(200回)を使い切りました。翌日にリセットされます。
|
|
230
|
+
|
|
231
|
+
### 「該当する企業が見つかりませんでした」と表示される
|
|
232
|
+
|
|
233
|
+
会社名を **正式名称** で入力してみてください。
|
|
234
|
+
- 悪い例:「トヨタ」
|
|
235
|
+
- 良い例:「トヨタ自動車株式会社」
|
|
147
236
|
|
|
148
|
-
|
|
149
|
-
- **部署・マーケ・キーマンはデータなしなら課金なし**です
|
|
150
|
-
- 1日のAPI上限はエンリッチメントパイプラインと共有です(全体900回中、MCP用に200回を確保)
|
|
151
|
-
- すべてのレスポンスに残りAPI回数が表示されます
|
|
237
|
+
法人番号がわかる場合は、そちらでも検索できます。
|
|
152
238
|
|
|
153
|
-
|
|
239
|
+
### 「複数の企業が存在します」と表示される
|
|
154
240
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
| `/mcp` で `failed` | 環境変数の設定ミス | `~/.claude.json` の env を確認 |
|
|
158
|
-
| エラーコード 102 | サービスキーが無効 | 管理者に有効なサービスキーを確認 |
|
|
159
|
-
| エラーコード 112 | 1日の上限超過 | 翌日まで待つ、または上限を確認 |
|
|
160
|
-
| エラーコード 204 | 企業が見つからない | 正式名称(株式会社○○)で再検索 |
|
|
161
|
-
| エラーコード 205 | 複数企業がマッチ | 法人番号やメールアドレスを追加で指定 |
|
|
241
|
+
検索条件が曖昧で、複数の企業がヒットしています。
|
|
242
|
+
会社名をより正確に入力するか、メールアドレスやホームページURLを追加で伝えてください。
|
package/dist/bizgate-client.d.ts
CHANGED
|
@@ -2,17 +2,37 @@ import type { BizGateConfig, BizGateDoc } from "./types.js";
|
|
|
2
2
|
import { UsageTracker } from "./usage-tracker.js";
|
|
3
3
|
/** Extract first element from a string array field, or return empty string. */
|
|
4
4
|
export declare function first(field: string[] | string | undefined): string;
|
|
5
|
+
interface CompanyResult {
|
|
6
|
+
matchPattern: string;
|
|
7
|
+
docs: BizGateDoc[];
|
|
8
|
+
}
|
|
9
|
+
interface DepartmentResult {
|
|
10
|
+
docs: BizGateDoc[];
|
|
11
|
+
numFound: number;
|
|
12
|
+
}
|
|
13
|
+
interface MarketingResult {
|
|
14
|
+
docs: BizGateDoc[];
|
|
15
|
+
}
|
|
16
|
+
interface KeymanResult {
|
|
17
|
+
docs: BizGateDoc[];
|
|
18
|
+
numFound: number;
|
|
19
|
+
}
|
|
5
20
|
export declare class BizGateClient {
|
|
6
21
|
private config;
|
|
7
22
|
private usageTracker;
|
|
23
|
+
private companyCache;
|
|
24
|
+
private departmentCache;
|
|
25
|
+
private marketingCache;
|
|
26
|
+
private keymanCache;
|
|
8
27
|
constructor(config: BizGateConfig, usageTracker: UsageTracker);
|
|
9
28
|
private buildUrl;
|
|
10
29
|
private getHeaders;
|
|
11
|
-
/** Send GET request and return parsed response. */
|
|
12
30
|
private request;
|
|
31
|
+
/** Build cache key from params. */
|
|
32
|
+
private cacheKey;
|
|
13
33
|
/**
|
|
14
34
|
* Company lookup (企業).
|
|
15
|
-
* Billed even on no-result
|
|
35
|
+
* Cached for 60s. Billed even on no-result.
|
|
16
36
|
*/
|
|
17
37
|
searchCompany(params: {
|
|
18
38
|
shogo?: string;
|
|
@@ -20,13 +40,10 @@ export declare class BizGateClient {
|
|
|
20
40
|
hpurl?: string;
|
|
21
41
|
email?: string;
|
|
22
42
|
tel?: string;
|
|
23
|
-
}): Promise<
|
|
24
|
-
matchPattern: string;
|
|
25
|
-
docs: BizGateDoc[];
|
|
26
|
-
}>;
|
|
43
|
+
}): Promise<CompanyResult>;
|
|
27
44
|
/**
|
|
28
45
|
* Department lookup (部署).
|
|
29
|
-
* Not billed on failure
|
|
46
|
+
* Cached for 60s. Not billed on failure.
|
|
30
47
|
*/
|
|
31
48
|
searchDepartments(params: {
|
|
32
49
|
shogo?: string;
|
|
@@ -35,24 +52,18 @@ export declare class BizGateClient {
|
|
|
35
52
|
cList?: string;
|
|
36
53
|
bKwd?: string;
|
|
37
54
|
bKOpr?: string;
|
|
38
|
-
}): Promise<
|
|
39
|
-
docs: BizGateDoc[];
|
|
40
|
-
numFound: number;
|
|
41
|
-
}>;
|
|
55
|
+
}): Promise<DepartmentResult>;
|
|
42
56
|
/**
|
|
43
57
|
* Marketing tags lookup (マーケティングタグ).
|
|
44
|
-
* Not billed on failure
|
|
58
|
+
* Cached for 60s. Not billed on failure.
|
|
45
59
|
*/
|
|
46
60
|
searchMarketingTags(params: {
|
|
47
61
|
shogo?: string;
|
|
48
62
|
compno?: string;
|
|
49
|
-
}): Promise<
|
|
50
|
-
docs: BizGateDoc[];
|
|
51
|
-
}>;
|
|
63
|
+
}): Promise<MarketingResult>;
|
|
52
64
|
/**
|
|
53
65
|
* Keyman lookup (キーマン・人名なし).
|
|
54
|
-
*
|
|
55
|
-
* Not billed on failure.
|
|
66
|
+
* Cached for 60s. Not billed on failure.
|
|
56
67
|
*/
|
|
57
68
|
searchKeyman(params: {
|
|
58
69
|
shogo?: string;
|
|
@@ -61,8 +72,28 @@ export declare class BizGateClient {
|
|
|
61
72
|
cList?: string;
|
|
62
73
|
bKwd?: string;
|
|
63
74
|
bKOpr?: string;
|
|
75
|
+
}): Promise<KeymanResult>;
|
|
76
|
+
/**
|
|
77
|
+
* Keyman with name lookup (キーマン・人名あり).
|
|
78
|
+
* Fetches details in parallel for speed.
|
|
79
|
+
*/
|
|
80
|
+
getKeymanDetails(keymanIDs: string[]): Promise<{
|
|
81
|
+
docs: BizGateDoc[];
|
|
82
|
+
}>;
|
|
83
|
+
/**
|
|
84
|
+
* Full keyman search with names (2-step).
|
|
85
|
+
*/
|
|
86
|
+
searchKeymanWithNames(params: {
|
|
87
|
+
shogo?: string;
|
|
88
|
+
compno?: string;
|
|
89
|
+
pList?: string;
|
|
90
|
+
cList?: string;
|
|
91
|
+
bKwd?: string;
|
|
92
|
+
bKOpr?: string;
|
|
93
|
+
limit?: number;
|
|
64
94
|
}): Promise<{
|
|
65
95
|
docs: BizGateDoc[];
|
|
66
|
-
|
|
96
|
+
totalFound: number;
|
|
67
97
|
}>;
|
|
68
98
|
}
|
|
99
|
+
export {};
|
package/dist/bizgate-client.js
CHANGED
|
@@ -1,13 +1,20 @@
|
|
|
1
1
|
import { BizGateApiError, BIZGATE_ERROR_CODES } from "./types.js";
|
|
2
|
+
import { Cache } from "./cache.js";
|
|
2
3
|
/** Extract first element from a string array field, or return empty string. */
|
|
3
4
|
export function first(field) {
|
|
4
5
|
if (Array.isArray(field))
|
|
5
6
|
return field[0] ?? "";
|
|
6
7
|
return field ?? "";
|
|
7
8
|
}
|
|
9
|
+
// Cache TTL: 60 seconds — same company searched within 60s won't hit the API again
|
|
10
|
+
const CACHE_TTL = 60_000;
|
|
8
11
|
export class BizGateClient {
|
|
9
12
|
config;
|
|
10
13
|
usageTracker;
|
|
14
|
+
companyCache = new Cache(CACHE_TTL);
|
|
15
|
+
departmentCache = new Cache(CACHE_TTL);
|
|
16
|
+
marketingCache = new Cache(CACHE_TTL);
|
|
17
|
+
keymanCache = new Cache(CACHE_TTL);
|
|
11
18
|
constructor(config, usageTracker) {
|
|
12
19
|
this.config = config;
|
|
13
20
|
this.usageTracker = usageTracker;
|
|
@@ -28,7 +35,6 @@ export class BizGateClient {
|
|
|
28
35
|
}
|
|
29
36
|
return {};
|
|
30
37
|
}
|
|
31
|
-
/** Send GET request and return parsed response. */
|
|
32
38
|
async request(skey, params) {
|
|
33
39
|
const url = this.buildUrl(skey, params);
|
|
34
40
|
const response = await fetch(url, { headers: this.getHeaders() });
|
|
@@ -36,7 +42,6 @@ export class BizGateClient {
|
|
|
36
42
|
throw new BizGateApiError(String(response.status), `HTTP ${response.status}: ${response.statusText}`);
|
|
37
43
|
}
|
|
38
44
|
const json = (await response.json());
|
|
39
|
-
// Error response: status=999, error.code + error.msg
|
|
40
45
|
if (json.responseHeader.status === 999) {
|
|
41
46
|
const err = json.responseHeader.error;
|
|
42
47
|
const code = err?.code ?? "unknown";
|
|
@@ -47,11 +52,23 @@ export class BizGateClient {
|
|
|
47
52
|
}
|
|
48
53
|
return json;
|
|
49
54
|
}
|
|
55
|
+
/** Build cache key from params. */
|
|
56
|
+
cacheKey(params) {
|
|
57
|
+
return Object.entries(params)
|
|
58
|
+
.filter(([, v]) => v)
|
|
59
|
+
.sort(([a], [b]) => a.localeCompare(b))
|
|
60
|
+
.map(([k, v]) => `${k}=${v}`)
|
|
61
|
+
.join("&");
|
|
62
|
+
}
|
|
50
63
|
/**
|
|
51
64
|
* Company lookup (企業).
|
|
52
|
-
* Billed even on no-result
|
|
65
|
+
* Cached for 60s. Billed even on no-result.
|
|
53
66
|
*/
|
|
54
67
|
async searchCompany(params) {
|
|
68
|
+
const key = this.cacheKey(params);
|
|
69
|
+
const cached = this.companyCache.get(key);
|
|
70
|
+
if (cached)
|
|
71
|
+
return cached;
|
|
55
72
|
this.usageTracker.increment();
|
|
56
73
|
const queryParams = {};
|
|
57
74
|
if (params.shogo)
|
|
@@ -65,16 +82,22 @@ export class BizGateClient {
|
|
|
65
82
|
if (params.tel)
|
|
66
83
|
queryParams.tel = params.tel;
|
|
67
84
|
const result = await this.request(this.config.skeyCompany, queryParams);
|
|
68
|
-
|
|
85
|
+
const data = {
|
|
69
86
|
matchPattern: result.responseHeader.matchpatern ?? "",
|
|
70
87
|
docs: result.response?.docs ?? [],
|
|
71
88
|
};
|
|
89
|
+
this.companyCache.set(key, data);
|
|
90
|
+
return data;
|
|
72
91
|
}
|
|
73
92
|
/**
|
|
74
93
|
* Department lookup (部署).
|
|
75
|
-
* Not billed on failure
|
|
94
|
+
* Cached for 60s. Not billed on failure.
|
|
76
95
|
*/
|
|
77
96
|
async searchDepartments(params) {
|
|
97
|
+
const key = this.cacheKey(params);
|
|
98
|
+
const cached = this.departmentCache.get(key);
|
|
99
|
+
if (cached)
|
|
100
|
+
return cached;
|
|
78
101
|
this.usageTracker.increment();
|
|
79
102
|
const queryParams = {};
|
|
80
103
|
if (params.shogo)
|
|
@@ -90,16 +113,22 @@ export class BizGateClient {
|
|
|
90
113
|
if (params.bKOpr)
|
|
91
114
|
queryParams.bKOpr = params.bKOpr;
|
|
92
115
|
const result = await this.request(this.config.skeyDepartment, queryParams);
|
|
93
|
-
|
|
116
|
+
const data = {
|
|
94
117
|
docs: result.response?.docs ?? [],
|
|
95
118
|
numFound: result.response?.numFound ?? 0,
|
|
96
119
|
};
|
|
120
|
+
this.departmentCache.set(key, data);
|
|
121
|
+
return data;
|
|
97
122
|
}
|
|
98
123
|
/**
|
|
99
124
|
* Marketing tags lookup (マーケティングタグ).
|
|
100
|
-
* Not billed on failure
|
|
125
|
+
* Cached for 60s. Not billed on failure.
|
|
101
126
|
*/
|
|
102
127
|
async searchMarketingTags(params) {
|
|
128
|
+
const key = this.cacheKey(params);
|
|
129
|
+
const cached = this.marketingCache.get(key);
|
|
130
|
+
if (cached)
|
|
131
|
+
return cached;
|
|
103
132
|
this.usageTracker.increment();
|
|
104
133
|
const queryParams = {};
|
|
105
134
|
if (params.shogo)
|
|
@@ -107,16 +136,21 @@ export class BizGateClient {
|
|
|
107
136
|
if (params.compno)
|
|
108
137
|
queryParams.compno = params.compno;
|
|
109
138
|
const result = await this.request(this.config.skeyMarketing, queryParams);
|
|
110
|
-
|
|
139
|
+
const data = {
|
|
111
140
|
docs: result.response?.docs ?? [],
|
|
112
141
|
};
|
|
142
|
+
this.marketingCache.set(key, data);
|
|
143
|
+
return data;
|
|
113
144
|
}
|
|
114
145
|
/**
|
|
115
146
|
* Keyman lookup (キーマン・人名なし).
|
|
116
|
-
*
|
|
117
|
-
* Not billed on failure.
|
|
147
|
+
* Cached for 60s. Not billed on failure.
|
|
118
148
|
*/
|
|
119
149
|
async searchKeyman(params) {
|
|
150
|
+
const key = this.cacheKey(params);
|
|
151
|
+
const cached = this.keymanCache.get(key);
|
|
152
|
+
if (cached)
|
|
153
|
+
return cached;
|
|
120
154
|
this.usageTracker.increment();
|
|
121
155
|
const queryParams = {};
|
|
122
156
|
if (params.shogo)
|
|
@@ -132,9 +166,64 @@ export class BizGateClient {
|
|
|
132
166
|
if (params.bKOpr)
|
|
133
167
|
queryParams.bKOpr = params.bKOpr;
|
|
134
168
|
const result = await this.request(this.config.skeyKeyman, queryParams);
|
|
135
|
-
|
|
169
|
+
const data = {
|
|
136
170
|
docs: result.response?.docs ?? [],
|
|
137
171
|
numFound: result.response?.numFound ?? 0,
|
|
138
172
|
};
|
|
173
|
+
this.keymanCache.set(key, data);
|
|
174
|
+
return data;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Keyman with name lookup (キーマン・人名あり).
|
|
178
|
+
* Fetches details in parallel for speed.
|
|
179
|
+
*/
|
|
180
|
+
async getKeymanDetails(keymanIDs) {
|
|
181
|
+
const fetchOne = async (id) => {
|
|
182
|
+
this.usageTracker.increment();
|
|
183
|
+
try {
|
|
184
|
+
const result = await this.request(this.config.skeyKeymanName, {
|
|
185
|
+
keymanID: id,
|
|
186
|
+
});
|
|
187
|
+
return result.response?.docs?.[0] ?? null;
|
|
188
|
+
}
|
|
189
|
+
catch {
|
|
190
|
+
return null;
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
// Parallel fetch (max 5 concurrent)
|
|
194
|
+
const results = [];
|
|
195
|
+
const batchSize = 5;
|
|
196
|
+
for (let i = 0; i < keymanIDs.length; i += batchSize) {
|
|
197
|
+
const batch = keymanIDs.slice(i, i + batchSize);
|
|
198
|
+
const batchResults = await Promise.all(batch.map(fetchOne));
|
|
199
|
+
for (const doc of batchResults) {
|
|
200
|
+
if (doc)
|
|
201
|
+
results.push(doc);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
return { docs: results };
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Full keyman search with names (2-step).
|
|
208
|
+
*/
|
|
209
|
+
async searchKeymanWithNames(params) {
|
|
210
|
+
const { docs: keymanDocs, numFound } = await this.searchKeyman({
|
|
211
|
+
shogo: params.shogo,
|
|
212
|
+
compno: params.compno,
|
|
213
|
+
pList: params.pList,
|
|
214
|
+
cList: params.cList,
|
|
215
|
+
bKwd: params.bKwd,
|
|
216
|
+
bKOpr: params.bKOpr,
|
|
217
|
+
});
|
|
218
|
+
if (keymanDocs.length === 0) {
|
|
219
|
+
return { docs: [], totalFound: 0 };
|
|
220
|
+
}
|
|
221
|
+
const maxDetails = params.limit ?? 10;
|
|
222
|
+
const ids = keymanDocs
|
|
223
|
+
.slice(0, maxDetails)
|
|
224
|
+
.map((d) => d.id)
|
|
225
|
+
.filter((id) => !!id);
|
|
226
|
+
const { docs: detailDocs } = await this.getKeymanDetails(ids);
|
|
227
|
+
return { docs: detailDocs, totalFound: numFound };
|
|
139
228
|
}
|
|
140
229
|
}
|
package/dist/cache.d.ts
ADDED
package/dist/cache.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/** Simple in-memory TTL cache. */
|
|
2
|
+
export class Cache {
|
|
3
|
+
ttlMs;
|
|
4
|
+
store = new Map();
|
|
5
|
+
constructor(ttlMs) {
|
|
6
|
+
this.ttlMs = ttlMs;
|
|
7
|
+
}
|
|
8
|
+
get(key) {
|
|
9
|
+
const entry = this.store.get(key);
|
|
10
|
+
if (!entry)
|
|
11
|
+
return undefined;
|
|
12
|
+
if (Date.now() > entry.expires) {
|
|
13
|
+
this.store.delete(key);
|
|
14
|
+
return undefined;
|
|
15
|
+
}
|
|
16
|
+
return entry.data;
|
|
17
|
+
}
|
|
18
|
+
set(key, data) {
|
|
19
|
+
this.store.set(key, { data, expires: Date.now() + this.ttlMs });
|
|
20
|
+
}
|
|
21
|
+
has(key) {
|
|
22
|
+
return this.get(key) !== undefined;
|
|
23
|
+
}
|
|
24
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -12,6 +12,7 @@ const skeyCompany = process.env.BIZGATE_SKEY_COMPANY;
|
|
|
12
12
|
const skeyDepartment = process.env.BIZGATE_SKEY_DEPARTMENT;
|
|
13
13
|
const skeyMarketing = process.env.BIZGATE_SKEY_MARKETING ?? "";
|
|
14
14
|
const skeyKeyman = process.env.BIZGATE_SKEY_KEYMAN ?? "";
|
|
15
|
+
const skeyKeymanName = process.env.BIZGATE_SKEY_KEYMAN_NAME ?? "";
|
|
15
16
|
if (!skeyCompany || !skeyDepartment) {
|
|
16
17
|
console.error("Error: BIZGATE_SKEY_COMPANY and BIZGATE_SKEY_DEPARTMENT environment variables are required");
|
|
17
18
|
process.exit(1);
|
|
@@ -39,6 +40,7 @@ const config = {
|
|
|
39
40
|
skeyDepartment,
|
|
40
41
|
skeyMarketing,
|
|
41
42
|
skeyKeyman,
|
|
43
|
+
skeyKeymanName,
|
|
42
44
|
authMode,
|
|
43
45
|
username: process.env.BIZGATE_USERNAME,
|
|
44
46
|
password: process.env.BIZGATE_PASSWORD,
|
|
@@ -192,17 +194,19 @@ server.tool("bizgate__company_search", "会社名または法人番号で企業
|
|
|
192
194
|
}
|
|
193
195
|
});
|
|
194
196
|
// ---------- Tool 2: 部署検索 ----------
|
|
195
|
-
server.tool("bizgate__department_search", "会社名または法人番号で部署情報(部署名・住所・電話番号・カテゴリ)を検索する。最大500
|
|
197
|
+
server.tool("bizgate__department_search", "会社名または法人番号で部署情報(部署名・住所・電話番号・カテゴリ)を検索する。最大500件。都道府県・カテゴリ・部署名キーワードで絞り込み可能。デフォルトで上位30件を表示(limitで変更可能)。", {
|
|
196
198
|
shogo: z.string().optional().describe("会社名(例:株式会社○○)"),
|
|
197
199
|
compno: z.string().optional().describe("法人番号(13桁)"),
|
|
198
200
|
pList: z.string().optional().describe("都道府県コード(カンマ区切り。例: 13,14 = 東京都,神奈川県)"),
|
|
199
201
|
cList: z.string().optional().describe("部署カテゴリ番号(カンマ区切り。1=経営企画,2=営業企画,3=人事,4=経理,5=総務,6=広報IR,7=法務,8=研究,9=購買,10=システム,11=海外,12=環境CSR,13=営業,14=製造工場,15=その他)"),
|
|
200
202
|
bKwd: z.string().optional().describe("部署名キーワード(カンマ区切りで複数可。例: 人事部,経理部)"),
|
|
201
203
|
bKOpr: z.string().optional().describe("キーワード結合演算子(0=OR(デフォルト), 1=AND)"),
|
|
202
|
-
|
|
204
|
+
limit: z.number().optional().describe("表示する件数の上限(デフォルト: 30)"),
|
|
205
|
+
}, async ({ shogo, compno, pList, cList, bKwd, bKOpr, limit }) => {
|
|
203
206
|
const err = validateInput(shogo, compno);
|
|
204
207
|
if (err)
|
|
205
208
|
return { content: [{ type: "text", text: err }] };
|
|
209
|
+
const displayLimit = limit ?? 30;
|
|
206
210
|
try {
|
|
207
211
|
const { docs, numFound } = await client.searchDepartments({
|
|
208
212
|
shogo, compno, pList, cList, bKwd, bKOpr,
|
|
@@ -213,10 +217,14 @@ server.tool("bizgate__department_search", "会社名または法人番号で部
|
|
|
213
217
|
};
|
|
214
218
|
}
|
|
215
219
|
const companyName = f(docs[0].shogo);
|
|
216
|
-
const
|
|
217
|
-
const
|
|
220
|
+
const displayed = docs.slice(0, displayLimit);
|
|
221
|
+
const header = `## 部署情報${companyName ? `: ${companyName}` : ""}(全${numFound}件中${displayed.length}件表示)\n`;
|
|
222
|
+
const text = displayed.map((d, i) => formatDepartmentDoc(d, i + 1)).join("\n\n");
|
|
223
|
+
const truncNote = docs.length > displayLimit
|
|
224
|
+
? `\n\n> 残り${numFound - displayLimit}件あります。キーワード(bKwd)やカテゴリ(cList)で絞り込むか、limitを増やしてください。`
|
|
225
|
+
: "";
|
|
218
226
|
return {
|
|
219
|
-
content: [{ type: "text", text: header + text + usageFooter() }],
|
|
227
|
+
content: [{ type: "text", text: header + text + truncNote + usageFooter() }],
|
|
220
228
|
};
|
|
221
229
|
}
|
|
222
230
|
catch (e) {
|
|
@@ -247,14 +255,21 @@ server.tool("bizgate__marketing_tags", "会社名または法人番号で企業
|
|
|
247
255
|
const lines = [`## マーケティングタグ: ${f(doc.shogo)}`];
|
|
248
256
|
if (doc.compno)
|
|
249
257
|
lines.push(`法人番号: ${doc.compno}`);
|
|
258
|
+
const formatTags = (raw) => {
|
|
259
|
+
return raw
|
|
260
|
+
.split("/")
|
|
261
|
+
.filter((t) => t.trim())
|
|
262
|
+
.map((t) => `- ${t.trim()}`)
|
|
263
|
+
.join("\n");
|
|
264
|
+
};
|
|
250
265
|
if (doc.snstag)
|
|
251
|
-
lines.push(`\n### SNSタグ\n${doc.snstag
|
|
266
|
+
lines.push(`\n### SNSタグ\n${formatTags(doc.snstag)}`);
|
|
252
267
|
if (doc.matag)
|
|
253
|
-
lines.push(`\n### MAツール\n${doc.matag
|
|
268
|
+
lines.push(`\n### MAツール\n${formatTags(doc.matag)}`);
|
|
254
269
|
if (doc.servicetag)
|
|
255
|
-
lines.push(`\n### 事業サービス\n${doc.servicetag
|
|
270
|
+
lines.push(`\n### 事業サービス\n${formatTags(doc.servicetag)}`);
|
|
256
271
|
if (doc.activtag)
|
|
257
|
-
lines.push(`\n### 活動タグ\n${doc.activtag
|
|
272
|
+
lines.push(`\n### 活動タグ\n${formatTags(doc.activtag)}`);
|
|
258
273
|
return {
|
|
259
274
|
content: [{ type: "text", text: lines.join("\n") + usageFooter() }],
|
|
260
275
|
};
|
|
@@ -263,26 +278,28 @@ server.tool("bizgate__marketing_tags", "会社名または法人番号で企業
|
|
|
263
278
|
return { content: [{ type: "text", text: errorText(e) }] };
|
|
264
279
|
}
|
|
265
280
|
});
|
|
266
|
-
// ---------- Tool 4:
|
|
267
|
-
server.tool("bizgate__keyman_search", "
|
|
281
|
+
// ---------- Tool 4: キーマン検索(人名付き) ----------
|
|
282
|
+
server.tool("bizgate__keyman_search", "会社名または法人番号で人事情報(担当者名・部署・役職・電話番号・住所)を検索する。部署カテゴリやキーワードで絞り込み可能。デフォルトで上位10名の詳細を取得(limitで変更可能)。API消費: 1回(一覧取得)+ N回(詳細取得、Nはlimit数)。", {
|
|
268
283
|
shogo: z.string().optional().describe("会社名(例:株式会社○○)"),
|
|
269
284
|
compno: z.string().optional().describe("法人番号(13桁)"),
|
|
270
285
|
pList: z.string().optional().describe("都道府県コード(カンマ区切り)"),
|
|
271
286
|
cList: z.string().optional().describe("部署カテゴリ番号(カンマ区切り。3=人事,13=営業 など)"),
|
|
272
|
-
bKwd: z.string().optional().describe("部署・役職キーワード(カンマ区切り。例:
|
|
287
|
+
bKwd: z.string().optional().describe("部署・役職キーワード(カンマ区切り。例: 役員,部長,営業)"),
|
|
273
288
|
bKOpr: z.string().optional().describe("キーワード結合演算子(0=OR(デフォルト), 1=AND)"),
|
|
274
|
-
|
|
289
|
+
limit: z.number().optional().describe("詳細取得する人数の上限(デフォルト: 10、最大: 50)。API消費に注意。"),
|
|
290
|
+
}, async ({ shogo, compno, pList, cList, bKwd, bKOpr, limit }) => {
|
|
275
291
|
const err = validateInput(shogo, compno);
|
|
276
292
|
if (err)
|
|
277
293
|
return { content: [{ type: "text", text: err }] };
|
|
278
|
-
if (!skeyKeyman) {
|
|
294
|
+
if (!skeyKeyman || !skeyKeymanName) {
|
|
279
295
|
return {
|
|
280
|
-
content: [{ type: "text", text: "エラー: BIZGATE_SKEY_KEYMAN が設定されていません。" }],
|
|
296
|
+
content: [{ type: "text", text: "エラー: BIZGATE_SKEY_KEYMAN および BIZGATE_SKEY_KEYMAN_NAME が設定されていません。" }],
|
|
281
297
|
};
|
|
282
298
|
}
|
|
299
|
+
const maxLimit = Math.min(limit ?? 10, 50);
|
|
283
300
|
try {
|
|
284
|
-
const { docs,
|
|
285
|
-
shogo, compno, pList, cList, bKwd, bKOpr,
|
|
301
|
+
const { docs, totalFound } = await client.searchKeymanWithNames({
|
|
302
|
+
shogo, compno, pList, cList, bKwd, bKOpr, limit: maxLimit,
|
|
286
303
|
});
|
|
287
304
|
if (docs.length === 0) {
|
|
288
305
|
return {
|
|
@@ -290,8 +307,24 @@ server.tool("bizgate__keyman_search", "会社名または法人番号で人事
|
|
|
290
307
|
};
|
|
291
308
|
}
|
|
292
309
|
const companyName = f(docs[0].shogo);
|
|
293
|
-
const header = `## 人事情報${companyName ? `: ${companyName}` : ""}(全${
|
|
294
|
-
const text = docs
|
|
310
|
+
const header = `## 人事情報${companyName ? `: ${companyName}` : ""}(全${totalFound}件中、上位${docs.length}件の詳細)\n`;
|
|
311
|
+
const text = docs
|
|
312
|
+
.map((d, i) => {
|
|
313
|
+
const lines = [`${i + 1}. ${f(d.ceo) || "(氏名不明)"}`];
|
|
314
|
+
lines.push(` 役職: ${f(d.bumon) || "(不明)"}`);
|
|
315
|
+
if (f(d.tel))
|
|
316
|
+
lines.push(` 電話: ${f(d.tel)}`);
|
|
317
|
+
if (f(d.add))
|
|
318
|
+
lines.push(` 住所: ${f(d.add)}`);
|
|
319
|
+
if (d.haturei)
|
|
320
|
+
lines.push(` 発令日: ${d.haturei}`);
|
|
321
|
+
if (d.pagedate)
|
|
322
|
+
lines.push(` 発表日: ${d.pagedate}`);
|
|
323
|
+
if (d.bikou)
|
|
324
|
+
lines.push(` 備考: ${d.bikou}`);
|
|
325
|
+
return lines.join("\n");
|
|
326
|
+
})
|
|
327
|
+
.join("\n\n");
|
|
295
328
|
return {
|
|
296
329
|
content: [{ type: "text", text: header + text + usageFooter() }],
|
|
297
330
|
};
|
|
@@ -301,7 +334,7 @@ server.tool("bizgate__keyman_search", "会社名または法人番号で人事
|
|
|
301
334
|
}
|
|
302
335
|
});
|
|
303
336
|
// ---------- Tool 5: 企業総合検索(企業+部署+キーマンを一括取得) ----------
|
|
304
|
-
server.tool("bizgate__company_full", "会社名または法人番号で企業情報・部署情報・人事情報を一括取得する。個別ツールを3回呼ぶ代わりに1回で全情報を取得可能。API 3
|
|
337
|
+
server.tool("bizgate__company_full", "会社名または法人番号で企業情報・部署情報・人事情報を一括取得する。個別ツールを3回呼ぶ代わりに1回で全情報を取得可能。API 3回分を消費。部署は上位15件、人事は役職一覧のみ(人名は含まない)。人名が必要な場合はbizgate__keyman_searchを別途使用。", {
|
|
305
338
|
shogo: z.string().optional().describe("会社名(例:株式会社○○)"),
|
|
306
339
|
compno: z.string().optional().describe("法人番号(13桁)"),
|
|
307
340
|
hpurl: z.string().optional().describe("ホームページURL(企業特定精度向上)"),
|
|
@@ -329,15 +362,19 @@ server.tool("bizgate__company_full", "会社名または法人番号で企業情
|
|
|
329
362
|
catch (e) {
|
|
330
363
|
sections.push(`企業情報: ${e instanceof Error ? e.message : "取得失敗"}`);
|
|
331
364
|
}
|
|
332
|
-
// 2. Department info
|
|
365
|
+
// 2. Department info (top 15 for token efficiency)
|
|
333
366
|
try {
|
|
334
367
|
const { docs, numFound } = await client.searchDepartments({
|
|
335
368
|
shogo, compno, bKwd, cList,
|
|
336
369
|
});
|
|
337
370
|
if (docs.length > 0) {
|
|
371
|
+
const displayed = docs.slice(0, 15);
|
|
338
372
|
const companyName = f(docs[0].shogo);
|
|
339
|
-
sections.push(`\n## 部署情報${companyName ? `: ${companyName}` : ""}(全${numFound}
|
|
340
|
-
sections.push(
|
|
373
|
+
sections.push(`\n## 部署情報${companyName ? `: ${companyName}` : ""}(全${numFound}件中${displayed.length}件表示)`);
|
|
374
|
+
sections.push(displayed.map((d, i) => formatDepartmentDoc(d, i + 1)).join("\n\n"));
|
|
375
|
+
if (numFound > 15) {
|
|
376
|
+
sections.push(`\n> 残り${numFound - 15}件はbizgate__department_searchで個別に取得できます。`);
|
|
377
|
+
}
|
|
341
378
|
}
|
|
342
379
|
else {
|
|
343
380
|
sections.push("\n## 部署情報\n該当なし");
|
package/dist/types.d.ts
CHANGED