PatrolTech について
PatrolTechは、警備巡回業務向けのリモートMCPサーバーです。ユーザーの認可に基づき、AIアシスタントが巡回やルート、チェックポイント、人員、インシデントなどのアカウントデータを読み取り、操作できます。変更は提案としてまとめられ、実行前に確認が必要です。
主な機能
- 01巡回、ルート、チェックポイント情報の読み取り
- 02警備員、拠点、インシデント、スキャンへのアクセス
- 03変更の提案と確認または取り消し
- 04OAuthとロールによるアクセス認可
活用シーン
- 01巡回ルートとチェックポイント状況の確認
- 02インシデント記録と警備員の活動データの確認
- 03確認前にアカウント変更の一括内容を点検
MCP 対応
リモートサーバーは、PatrolTechアカウントデータの読み取り、変更の提案、提案の確認・取り消し、拠点のQRシート取得に使うツールをMCPクライアントに提供します。クライアントはOAuthで接続し、権限とスコープはPatrolTech APIが適用します。
設定
リモートサーバーはインストール不要です。クライアントを選んで設定をコピーするか、ワンクリックで導入できます。
https://mcp.patroltech.online/mcpclaude mcp add --transport http online-patroltech-patroltech https://mcp.patroltech.online/mcp{"mcpServers":{"online-patroltech-patroltech":{"type":"http","url":"https://mcp.patroltech.online/mcp"}}}Cursor で開く{"servers":{"online-patroltech-patroltech":{"type":"http","url":"https://mcp.patroltech.online/mcp"}}}VS Code で開く{"mcpServers":{"online-patroltech-patroltech":{"type":"http","url":"https://mcp.patroltech.online/mcp"}}}{"mcpServers":{"online-patroltech-patroltech":{"serverUrl":"https://mcp.patroltech.online/mcp"}}}コマンドはターミナルで実行し、JSON は各クライアントの MCP 設定に貼り付けて再起動します。認可が必要なサーバーは初回接続時にログインを求めます。
ツール
詳細
PatrolTech MCP サーバー
PatrolTechのリモートModel Context Protocolサーバーです。PatrolTechは、警備巡回とセキュリティパトロールのプラットフォームです。Claude、ChatGPT、Copilot、Gemini、CursorなどのAIアシスタントが、OAuthでサインインしたユーザーに代わって、PatrolTechアカウントの情報を読み取り、操作できます。対象は、巡回、ルート、チェックポイント、警備員、インシデント、ユーザー、場所、アクセス制御、スキャンです。
このリポジトリにはサーバーコードのみが含まれています。アシスタントにコネクターをインストールするには、PatrolTech/ai-integrationsを使用してください。プラグイン、MCP Registryのエントリー、各クライアント向けの手順が含まれています。
このサーバー単体ではアクセス権を付与しません。 サーバー独自の認証情報はなく、ユーザーのトークンを転送します。すべての呼び出しはPatrolTech APIによって認可されます(組織と場所のロール、OAuthスコープ、エージェントに許可される書き込み操作の限定リスト)。詳しくはSECURITY.mdをご覧ください。
動作の仕組み
MCP client ──OAuth──▶ PatrolTech authorization server
│ Bearer access token (audience = MCP_PUBLIC_URL)
▼
MCP server (this repo, stateless) ──agent session──▶ PatrolTech API
│ ▲
└── Redis: locks and rate limits └── @patroltech/agent-capabilities + @patroltech/sdk-api
- OAuthリソースサーバー。
/mcpには、PatrolTech認可サーバーが発行したベアラートークンが必要です(/.well-known/oauth-protected-resource/mcpにあるRFC 9728メタデータ)。トークンはAPIのJWKS(ES256、発行者とオーディエンスの完全一致)に照らして検証され、15分間のエージェントセッション(POST /oauth/agent-session)と交換されます。セッションはトークンのハッシュをキーにキャッシュされます。APIは、許可が引き続き有効な範囲にセッションを制限します。 - ステートレス。 リクエストごとに新しいMCPサーバーインスタンスを作成し、プロトコルの両方の世代(2025および2026-07-28)に対応します。会話に関する情報をメモリに保持しません。提案はPatrolTech APIに保存されるため、任意の数のワーカーで同じユーザーのリクエストを処理できます。
- Redisは、ワーカー間で共有する必要がある情報を保持します。提案に関するユーザーごとのロック(
SET NX PX、有効期間中に更新)と、ユーザーおよびツールごとのレート制限です。productionとstagingでは必須です。Redisに障害が発生した場合、提案、確定、キャンセルの各操作は、2つの提案が互いを上書きするリスクを避けるため、「busy」と応答します。REDIS_URLがない場合(開発環境とテスト環境のみ)、どちらもプロセスメモリ内に保持されます。 - ツールは、
@patroltech/agent-capabilitiesのmcpチャネルから取得します。このチャネルは、@patroltech/sdk-apiを通じてAPIを呼び出します。
ツール
| ツール | 機能 |
|---|---|
patroltech_<area>_<read> | カタログの各読み取り操作につき1つあります。読み取り専用で、タイトルと説明は英語です。ユーザーが複数の組織に所属している場合は、任意で organization を指定します。 |
patroltech_account_get_context | ユーザーの組織(名前、役割、アクセス権)と所在地を返します。説明には、この接続の確認場所(DASHBOARD_URL、Connected apps)が記載されています。 |
patroltech_<area>_propose_<verb> | 変更を提案します。確認されるまで変更は適用されません。1人のユーザーとクライアントによる提案は1つのバッチを構成します(最大10件、有効期限は30分)。 |
patroltech_proposals_confirm | 提案されたパラメーターを使って、保留中のバッチ全体を順番に実行します(破壊的操作としてマークされており、クライアントはまずユーザーに確認します)。 |
patroltech_proposals_cancel | 保留中のバッチを取り消します。 |
patroltech_locations_get_qr_sheet | ロケーションの印刷可能なQRシートへの署名付きリンク(有効期間1時間)を返します。 |
サーバーは instructions(src/interface/mcp/serverInstructions.ts)も送信します。これは複数のツールにまたがるガイダンスで、警備員を比較する際にランキングツールを使うことや、比較結果を人への評価ではなく活動データとして提示することなどが含まれます。
書き込みには write スコープが必要です。これがない場合、サーバーは read write チャレンジとともに 403 insufficient_scope を返します。各結果は { data, truncated?, notices?, note } 形式で、最大60,000文字です。note は、data が指示ではなくデータであることを示します。各ユーザーは、読み取りツールを毎分60回、書き込みツールを毎分20回呼び出せます。各呼び出しでは、引数そのものではなく引数のハッシュを含む mcp.tool_call 監査行が1つ記録されます。
エンドポイント
| パス | 認証 | 用途 |
|---|---|---|
/mcp(MCP_PUBLIC_URL のパス) | Bearer | MCP エンドポイント(POST、GET、DELETE)。Host を検証し、すべての Origin を拒否します。 |
/.well-known/oauth-protected-resource/mcp | なし | 保護リソースのメタデータ(RFC 9728)。ルートパスでも利用できます。 |
/health | なし | 稼働状態:200 {"status":"ok","version":"…"}。 |
/health/ready | なし | JWKS が3秒以内に応答し、REDIS_URL が設定されている場合は Redis が PING に応答すれば 200、それ以外は 503。 |
/.well-known/openai-apps-challenge | なし | ChatGPT アプリディレクトリ用の OPENAI_APPS_CHALLENGE トークン。未設定の場合は 404 を返します。 |
設定
すべての変数は .env.example に記載されています。設定が無効な場合、サーバーは起動を拒否し、不足している変数または無効な変数を一覧表示します。
| 変数 | 必須 | 説明 |
|---|---|---|
MCP_PUBLIC_URL | はい | MCP エンドポイントの正確な公開 URL。トークンの対象(例:https://mcp.example.com/mcp)です。 |
API_BASE_URL | はい | /api を含まない PatrolTech API のオリジンです。 |
OAUTH_ISSUER | はい | アクセストークンの想定される iss。バイト単位で一致する必要があります。 |
OAUTH_JWKS_URL | いいえ | 発行者の JWKS です。デフォルトは API_BASE_URL + /oauth/jwks.json です。 |
DASHBOARD_URL, APP_BASE_URL | はい | ユーザーに表示するリンク用の PatrolTech ダッシュボードとウェブアプリです。 |
APP_ENVIRONMENT | はい | production、staging、development、または test です。 |
REDIS_URL | production および staging で必須 | 共有 Redis(ioredis URL)です。 |
REDIS_NAMESPACE | いいえ | Redis のキー接頭辞です。デフォルトは APP_ENVIRONMENT です。 |
HOST, PORT | いいえ | プロセスのリッスン先です。デフォルトは 127.0.0.1:3110(リバースプロキシの背後)です。 |
LOG_LEVEL | いいえ | debug、info(デフォルト)、warn、または error です。監査ログとハートビートの行は、どのレベルでも出力されます。 |
SERVICE_NAME | いいえ | 各ログ行の service フィールドです。デフォルトは mcp-server です。 |
OPENAI_APPS_CHALLENGE | いいえ | ChatGPT アプリディレクトリ用のドメイン検証トークンです。 |
ログは、stdout と stderr に1行につき1つの JSON オブジェクトとして出力されます。各プロセスは5分ごとに mcp.heartbeat 行を書き込むため、ログモニターで停止を検知してアラートを出せます。
開発
Node.js 22.9 以降が必要です。
npm ci
cp .env.example .env.local # fill in the values; .env.local is ignored by git
npm run dev # tsx watch, loads .env.local
curl http://127.0.0.1:3110/health
| スクリプト | |
|---|---|
npm run dev | リロード付きで実行します(tsx watch)。 |
npm run lint、npm run format:check、npm run typecheck | ESLint、Prettier、ソースとテストの型チェックを実行します。 |
npm test | ユニットテストと HTTP テストを実行します(vitest)。 |
npm run test:deploy | PM2 のエコシステムとリモートデプロイスクリプトのテストを実行します。 |
npm run build | dist/ にコンパイルします(npm start で実行できます)。 |
npm run bundle | 自己完結型の ESM ファイル dist/bundle/server.mjs(およびソースマップ)を作成します。デプロイ可能な成果物です。 |
npm run smoke | テスト用設定でバンドルを起動し、/health、メタデータ、チャレンジ、および到達不能な JWKS と Redis が /health/ready に報告されることを確認します。 |
コードはヘキサゴナルスタイルに沿って構成されています。src/domain(純粋なルール)、src/application(ユースケースとそのポート)、src/interface/mcp(MCP アダプター)、src/infrastructure(HTTP、OAuth、SDK アダプター、Redis、ロギング)があります。
セルフホスティング
このサーバーは、自身のインフラストラクチャ上で実行できます。たとえば、監査したり、自身のネットワークポリシーの前段に配置したりできます。
OAuth のオーディエンス。 アクセストークンは、発行対象のリソースに紐付けられます。PatrolTech 認可サーバーは、認識しているリソースに対してのみトークンを発行するため、独自の MCP_PUBLIC_URL でデプロイする場合、PatrolTech ユーザーが接続する前に PatrolTech への登録が必要です。SECURITY.md に記載されている連絡手段からお問い合わせください。
必要なもの:
- Node.js 22.9 以降と Redis。
HOST:PORTの前段に配置し、TLS を提供するリバースプロキシ。/mcp、/.well-known/oauth-protected-resource(およびそのサブパス)、使用する場合は/health、/health/ready、/.well-known/openai-apps-challengeを転送する必要があります。Hostヘッダーは保持してください。サーバーが受け付けるのは、MCP_PUBLIC_URLのホストまたはループバックだけです。
手順:
- 成果物をビルドします:
npm ci && npm run bundle && npm run smoke。 dist/bundle/server.mjs、dist/bundle/server.mjs.map、package.json(バージョンはここから取得されます)をサーバー上のディレクトリにコピーします。サーバー上でnpm installを実行する必要はありません。- そのディレクトリに
.env.localを作成し、.env.exampleを元にAPP_ENVIRONMENT=productionとREDIS_URLを設定します。 node --enable-source-maps --env-file-if-exists=.env.local server.mjsで起動するか、PM2(以下を参照)で起動します。プロセスはSIGTERMを受けると正常に停止し、進行中の呼び出しを最大 55 秒待機します。強制終了する場合は、約 60 秒待ってください。
PM2 を使う場合
deploy/ecosystem.config.cjs は、バンドルをクラスター モードで実行します。サーバーのデータは保持せず、環境変数から MCP_PM2_NAME、MCP_PORT、MCP_APP_ENVIRONMENT(必須)と MCP_INSTANCES、MCP_SERVICE_NAME、PM2_APP_DIR(任意)を読み込み、残りは .env.local から読み込みます。
MCP_PM2_NAME=mcp MCP_PORT=3110 MCP_APP_ENVIRONMENT=production MCP_INSTANCES=2 \
pm2 start ecosystem.config.cjs
クラスター モードでは、ワーカーは PM2 デーモンの Node.js で実行されます。--env-file-if-exists を使用するには、Node.js が 22.9 以降である必要があります。共有デーモンで pm2 update を実行しないでください。管理しているすべてのアプリが再起動されます。
GitHub Actions を使用する
.github/workflows/deploy.yml は、このリポジトリのフォークを SSH 経由で手動でデプロイします(デフォルトは staging の workflow_dispatch)。シークレットを使わずにバンドルをビルド、テスト、スモークテストし、バンドル、package.json、エコシステムを rsync でアップロードしてから、サーバー上で deploy/remote-deploy.sh を実行します。このスクリプトは .env.local を確認し、ダウンタイムなしで PM2 を再読み込みし、準備完了 URL をプローブして、すべてのインスタンスが新しいバージョンでオンラインになるまで待機します。production は main または v* タグからのみデプロイします。
ワークフローとスクリプトにサーバーのデータは含まれておらず、ログにもサーバーから取得した情報は出力されません。GitHub environments に staging と production を作成し(production には必須のレビュアーと、main および v* タグを対象とするデプロイブランチルールを設定)、それぞれに次の値を設定します。
| シークレット | 必須 | 説明 |
|---|---|---|
SSH_HOST | はい | サーバーのホスト名または IP アドレスです。 |
SSH_USER | はい | アプリのディレクトリを所有し、PM2 を実行する SSH ユーザーです。 |
SSH_PRIVATE_KEY | はい | デプロイにのみ使用する、そのユーザーのパスフレーズなしの秘密鍵です。 |
SSH_KNOWN_HOSTS | はい | サーバーの known_hosts 行です。帯域外で確認してください(ssh-keyscan -H <host>)。 |
APP_DIR | はい | アプリのディレクトリ(バンドル、.env.local、logs/)の絶対パスです。 |
PM2_APP_NAME | はい | PM2 プロセスの名前です。 |
APP_PORT | はい | プロセスがリッスンするローカルポートです。 |
HEALTH_URL | はい | サーバーから見た準備完了 URL です。http://127.0.0.1:<port>/health/ready を指定します。 |
SSH_PORT | いいえ | SSH ポートです。22 以外の場合に指定します。 |
DEPLOY_HOME | いいえ | PM2 デーモンとの通信に使う HOME(.pm2 がある場所)です。 |
NODE_BIN_DIR | いいえ | サーバーで使用する Node.js バイナリのディレクトリです。PATH の先頭に設定します。 |
PM2_BIN | いいえ | 使用する pm2 CLI のパスです。デフォルトは PATH 内のものです。 |
DEPLOY_LOCK_FILE | いいえ | 同じ PM2 デーモン上の他のアプリのデプロイと共有するロックファイル(flock)です。 |
FILE_OWNER | いいえ | アップロード後にアプリのディレクトリに設定する user:group です。 |
SERVICE_NAME | いいえ | ログ行の service です。デフォルトは PM2 プロセス名です。 |
DD_API_KEY | いいえ | デプロイ失敗時にイベントを送信するための Datadog API キーです。 |
| 変数 | 必須 | 説明 |
|---|---|---|
PM2_INSTANCES | いいえ | インスタンス数(デフォルトは 1)です。 |
DD_SITE | いいえ | 失敗イベントの送信先となる Datadog サイト(デフォルトは datadoghq.com)です。 |
サーバーのデータは変数ではなくシークレットに設定してください。Actions はログ内のシークレットをマスクし、ワークフローもシークレットから派生した値をマスクします。
バージョン管理とリリース
バージョンは package.json のみに記載されています。バージョンの変更が main に反映されると、リリースワークフローが v<version> タグを作成し、バンドルとそのチェックサムを含む GitHub リリースを作成します。
関連パッケージ
@patroltech/agent-capabilities:このサーバーが公開する読み取り項目と提案されたアクションのカタログです。@patroltech/sdk-api:PatrolTech の公開 API の TypeScript SDK です。- PatrolTech/ai-integrations:各 AI アシスタント向けのコネクターです。
ライセンス
MIT © Ingenieros Web SL
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。