概要
ACG SmartHR MCP は、あおぞらケアグループ(ACG)が社内利用のために構築した Model Context Protocol (MCP) サーバーです。
AI アシスタント(Claude)から SmartHR API を利用して人事データを安全に参照・更新できるようにします。 8 つのツールを提供し、従業員情報の閲覧・検索・更新・登録、部署・役職の参照、給与明細の参照が可能です。
アーキテクチャ
Core + Shell パターン
トランスポート非依存の Core(ビジネスロジック)と、 差し替え可能な Shell(接続方式)で構成されています。
Hono + Streamable HTTP"] end subgraph Core["Core(ビジネスロジック)"] AUTH["4層認証"] TOOLS["ツール定義
8ツール"] PII["PII フィルタ"] AUDIT["監査ログ"] RL["レート制限"] end SMARTHR["SmartHR API"] CC --> STDIO CD --> STDIO CW --> HTTP APP --> HTTP STDIO --> AUTH HTTP --> AUTH AUTH --> TOOLS TOOLS --> PII TOOLS --> AUDIT TOOLS --> RL RL --> SMARTHR style Core fill:#e0f2fe,stroke:#0284c7 style Shell fill:#f0fdf4,stroke:#16a34a style Clients fill:#fef3c7,stroke:#d97706
接続モード
| モード | トランスポート | 対象クライアント | 認証 |
|---|---|---|---|
| stdio | 標準入出力 | Claude Code, Claude Desktop | 環境変数(ローカル実行) |
| HTTP | Streamable HTTP | Cowork, claude.ai, 自社アプリ | OAuth 2.1(Google OIDC 委譲 + JWT) |
認証フロー
4 層認証モデル
SmartHR API トークンにスコープ制限がないため、アプリケーション側で 4 層の認証・認可を実装しています。
ロールとアクセス制御
Firestore 許可リストに登録されたアカウントのみ接続可能です。未登録のアカウントはドメイン内でもアクセスできません。
- ✅ 従業員の閲覧・検索
- ✅ 従業員の更新・新規登録
- ✅ 給与明細の閲覧
- ✅ 部署・役職の閲覧
- ✅ 生年月日・性別・連絡先を含む詳細情報
- ❌ 削除操作(未実装・スコープ外)
- ✅ 従業員の閲覧・検索
- ❌ 従業員の更新・新規登録
- ❌ 給与明細の閲覧
- ✅ 部署・役職の閲覧
- ❌ 生年月日・性別・連絡先(自動除外)
- ❌ 削除操作(未実装・スコープ外)
ツール別アクセス権限
| ツール | 操作内容 | 必要権限 | admin | readonly |
|---|---|---|---|---|
list_employees |
従業員一覧 | read | ✅ | ✅ |
get_employee |
従業員詳細 | read | ✅ | ✅ |
search_employees |
従業員検索 | read | ✅ | ✅ |
list_departments |
部署一覧 | read | ✅ | ✅ |
list_positions |
役職一覧 | read | ✅ | ✅ |
update_employee |
従業員情報の更新 | write | ✅ | ❌ |
create_employee |
従業員の新規登録 | write | ✅ | ❌ |
get_pay_statements |
給与明細の取得 | pay_statements | ✅ | ❌ |
※ 削除操作(DELETE)は全ロールで利用不可(未実装・安全性のためスコープ外)
⚠️ コネクタ設定画面の表示について
claude.ai のコネクタ設定画面にはサーバーが提供する全ツールが一覧表示されますが、表示 ≠ 実行可能です。 各ツールの実行時にサーバー側でユーザーの権限を検証し、権限不足の場合はリクエストを拒否します(fail-closed)。
ツール一覧
list_employees
readonly
従業員一覧を取得します。ページネーション対応。
パラメータ
page | ページ番号(1始まり、任意) |
per_page | 1ページあたりの件数(最大100、任意) |
使用例(Claude への指示)
"従業員一覧を10件取得して"
get_employee
readonly
従業員IDを指定して詳細情報を取得します。
パラメータ
id * | SmartHR 従業員ID(必須) |
使用例
"従業員ID abc123 の詳細を見せて"
search_employees
readonly
名前・社員番号などで従業員を検索します。
パラメータ
query * | 検索キーワード(必須) |
page | ページ番号(任意) |
per_page | 1ページあたりの件数(任意) |
使用例
"田中さんの情報を検索して"
get_pay_statements
pay_statements
給与明細を取得します。従業員ID・年・月で絞り込み可能。pay_statements 権限必須。
パラメータ
crew_id | 従業員ID(任意) |
year | 年(例: 2026、任意) |
month | 月(1-12、任意) |
page | ページ番号(任意) |
per_page | 1ページあたりの件数(任意) |
使用例
"2026年3月の給与明細を見せて"
list_departments
readonly
部署一覧を取得します。
パラメータ
page | ページ番号(任意) |
per_page | 1ページあたりの件数(任意) |
使用例
"部署の一覧を表示して"
list_positions
readonly
役職一覧を取得します。
パラメータ
page | ページ番号(任意) |
per_page | 1ページあたりの件数(任意) |
使用例
"役職の一覧を整理して"
update_employee
write
従業員情報を部分更新します(PATCH)。変更するフィールドのみ指定します。
パラメータ
id * | SmartHR 従業員ID(必須) |
last_name | 姓(任意) |
first_name | 名(任意) |
emp_code | 社員番号(任意) |
entered_at | 入社日(任意) |
resigned_at | 退職日(任意) |
department | 部署ID(任意) |
position | 役職ID(任意) |
使用例
"田中さんの部署を人事部に変更して"
create_employee
write
新しい従業員を SmartHR に登録します。
パラメータ
last_name * | 姓(必須) |
first_name * | 名(必須) |
emp_code | 社員番号(任意) |
entered_at | 入社日(任意) |
department | 部署ID(任意) |
position | 役職ID(任意) |
使用例
"新入社員の山田花子さん(社員番号: 2001、入社日: 2026-04-01)を登録して"
セットアップガイド
推奨 Cowork / claude.ai
管理者(組織オーナー)の操作(初回のみ):
- 設定 > コネクタ を開く
- カスタムコネクタを追加 をクリック
- 名前:
SmartHR - URL: MCP サーバーの
/mcpエンドポイント URL を入力 - 追加 をクリック
メンバーの操作:
- 設定 > コネクタ で「SmartHR」の 連携/連携させる をクリック
- Google アカウント(@aozora-cg.com)で認証
- 会話の + ボタン > コネクタ で SmartHR を ON にして使用
Claude Code(stdio)
.claude.json に以下を追加:
{
"mcpServers": {
"smarthr": {
"command": "npx",
"args": ["tsx", "packages/mcp-smarthr/src/index.ts"],
"env": {
"SMARTHR_API_KEY": "your-api-key",
"SMARTHR_TENANT_ID": "your-tenant-id",
"MCP_USER_EMAIL": "you@aozora-cg.com",
"MCP_USER_ROLE": "readonly"
}
}
}
}
Claude Desktop(stdio)
claude_desktop_config.json に以下を追加:
{
"mcpServers": {
"smarthr": {
"command": "node",
"args": ["/path/to/packages/mcp-smarthr/dist/index.js"],
"env": {
"SMARTHR_API_KEY": "your-api-key",
"SMARTHR_TENANT_ID": "your-tenant-id",
"MCP_USER_EMAIL": "you@aozora-cg.com",
"MCP_USER_ROLE": "readonly"
}
}
}
}
セキュリティ
Cloud Armor 移行予定"] OAUTH["OAuth 2.1
Google OIDC + JWT"] DOMAIN["ドメイン制限
@aozora-cg.com"] RBAC["パーミッション制御
read / write / pay"] PIIF["PII フィルタ
個人情報保護"] AUDITL["監査ログ
全操作記録"] end IP --> OAUTH --> DOMAIN --> RBAC --> PIIF --> AUDITL style Protection fill:#f0fdf4,stroke:#16a34a
IP アドレス制限(Cloud Armor 移行予定)
Cloud Armor による IP 制限を導入予定。Anthropic のサーバー IP 範囲のみ許可し、 直接アクセスを遮断します。現在は OAuth 2.1 認証で保護されています。
PII フィルタリング
readonly ロールでは生年月日・性別・メールアドレス・電話番号が自動的に除外されます。 マイナンバーは全ロールで除外されます。
監査ログ
全ツール呼び出しが構造化ログとして記録されます。 ツール名・ユーザーメール・パラメータ(PII マスク済み)・実行時間を含みます。
レート制限
SmartHR API のレート制限(10 req/sec)に合わせたトークンバケット方式のスロットリングを実装。 429 レスポンス時は自動リトライします。
デプロイ構成
mcp-smarthr"] SM["Secret Manager
API Key / Tenant ID"] FS["Firestore
監査ログ / 許可リスト"] CL["Cloud Logging
構造化ログ"] end CR --> SM CR --> FS CR --> CL CR --> SMARTHR["SmartHR API"] ANTHROPIC["Anthropic
(Cowork/claude.ai)"] --> CR style GCP fill:#e0f2fe,stroke:#0284c7
| コンポーネント | 技術スタック | 役割 |
|---|---|---|
| HTTP サーバー | Hono + @modelcontextprotocol/hono | MCP Streamable HTTP トランスポート |
| ランタイム | Node.js 22 (node:22-slim) | コンテナ実行環境 |
| OAuth 2.1 / JWT | jose + google-auth-library | JWT 検証 + Google OIDC 委譲 |
| セッション管理 | ステートレス | Cloud Run スケーリング対応 |
FAQ
データの書き込み・更新はできますか?
はい。write 権限を持つユーザーは、従業員情報の更新(update_employee)と
新規登録(create_employee)が可能です。AI は実行前に必ず変更内容を確認し、
ユーザーの承認を得てから SmartHR API を呼び出します。
更新可能なフィールドは氏名・社員番号・入退社日・部署・役職に限定されています。
誰がアクセスできますか?
@aozora-cg.com ドメインのユーザーのみです。Team プランでは管理者がコネクタを登録した後、 チームメンバー全員が利用可能になります。個人プランでは各自がコネクタを登録します。
給与情報は誰でも見られますか?
いいえ。pay_statements 権限を持つユーザーのみが get_pay_statements ツールを利用できます。
権限のないユーザーが呼び出すと「権限不足」エラーが返ります。
操作ログは残りますか?
はい。全てのツール呼び出しが監査ログに記録されます(ツール名、ユーザー、パラメータ、実行時間)。 パラメータ内の個人情報は自動的にマスキングされます。ログは 7 年間保持されます。
Claude が計算ミスをする心配はありませんか?
MCP サーバーは SmartHR のデータをそのまま返します。AI が計算や加工をすることはありません。 給与計算などの金銭計算は、別途確定的なプログラムコードで処理されます(ADR-007)。