Skip to main content
Glama

MCPController

MCPControllerは、単一管理者による医師管理用MCPアプリケーションです。ChatGPTはOAuth 2.1(PKCE付き)で接続し、管理者がログインして付与する医師権限を選択すると、MCPサーバーがMongoDBをバックエンドとする医師ツールを公開します。

アーキテクチャ

ChatGPT
  ↓
OAuth
  ↓
Admin Login
  ↓
Admin Consent
  ↓
Granted Permissions
  ↓
MCP Access Token
  ↓
MCP /mcp
  ↓
Permission Check
  ↓
Doctor Tools
  ↓
MongoDB

Related MCP server: aster-mcd-mcp-adapter

このアプリの機能

  • システム全体を所有する管理者は1人だけです。

  • 公開登録やマルチユーザーアカウントの切り替えはありません。

  • 管理者は環境変数の認証情報で認証します。

  • 同意画面で管理者はdoctor:read、doctor:write、doctor:deleteを承認できます。

  • MCPサーバーはツール呼び出しのたびに承認済みスコープを再確認します。

  • 医師データはシンプルなMongooseモデルを通じてMongoDBに保存されます。

認証

ブラウザセッションはMCPベアラートークンとは別です。

  • ブラウザセッション: 管理者UIと同意画面で使用するHTTP-onlyクッキー。

  • MCPアクセストークン: ChatGPTが/mcpに対して使用するベアラートークン。

  • OAuthはPKCE付きの認可コードフローを使用します。

  • 認可コードは一度きりで短時間しか有効ではありません。

  • アクセストークンとリフレッシュトークンは保存前にハッシュ化されます。

管理者ログインは.envのADMIN_EMAILとADMIN_PASSWORDを使用します。

医師管理

ドメインモデルは意図的に小さく保っています:

  • name - 必須文字列

  • specialization - 必須文字列

  • createdAt / updatedAt - Mongooseのタイムスタンプで管理

医師のCRUDはサービス層に実装され、REST管理者APIとMCPツール層の両方で再利用されます。

OAuthフロー

  1. ChatGPTが認可エンドポイントを開きます。

  2. 管理者が認証されていない場合、ブラウザは/loginに移動します。

  3. 管理者がログインします。

  4. 同意ページに要求された医師権限が表示されます。

  5. 管理者はサブセットを承認するか、リクエストを拒否します。

  6. 認可コードがアクセストークンと交換されます。

  7. ChatGPTはそのトークンを/mcpで使用します。

権限フロー

要求されたスコープは次のようにMCPツールにマッピングされます:

  • doctor:read → list_doctors、get_doctor

  • doctor:write → add_doctor、update_doctor

  • doctor:delete → delete_doctor

バックエンドは権限を2回強制します:

  • OAuthは承認済みスコープのみを認可コードとトークンに書き込みます。

  • 各MCPツールはMongoDBにアクセスする前にトークンのスコープを確認します。

MCPツール

ツール

スコープ

動作

list_doctors

doctor:read

すべての医師を返します

get_doctor

doctor:read

doctorIdで1人の医師を返します

add_doctor

doctor:write

nameとspecializationで医師を作成します

update_doctor

doctor:write

doctorIdで医師を更新します

delete_doctor

doctor:delete

doctorIdで医師を削除します

環境変数

ルートの.envファイルを使用します。アプリケーションはプロジェクトルートからそれを読み込みます。

ローカルのnpm run dev(Viteは5173、APIは3000)に必要な値:

NODE_ENV=development
PORT=3000
APP_URL=http://localhost:5173
API_URL=http://localhost:3000
MONGODB_URI=mongodb://127.0.0.1:27017/mcpcontroller
ADMIN_EMAIL=admin@example.com
ADMIN_PASSWORD=change-this-password
JWT_SECRET=change-this-to-a-long-random-secret
MCP_SERVER_NAME=MCPController
MCP_SERVER_VERSION=1.0.0

コードはトークン/セッションの有効期間変数も安全なデフォルト値付きでサポートしています:

  • JWT_EXPIRES_IN

  • AUTH_CODE_TTL_SECONDS

  • ACCESS_TOKEN_TTL_SECONDS

  • REFRESH_TOKEN_TTL_SECONDS

Vercelでは、APP_URLとAPI_URLの両方が公開HTTPSオリジンである必要があります(下記のデプロイを参照)。

ローカルセットアップ

  1. 依存関係をインストール:

npm install
  1. MongoDBをローカルで起動します。

  2. サンプルデータを投入:

npm run seed
  1. アプリを起動:

npm run dev

開発環境では、ReactクライアントはVite経由で実行され、APIリクエストをバックエンドにプロキシします。

テスト

自動チェックを実行:

npm test

クライアントビルドを実行:

npm run build

現在のテストスイートは以下をカバーしています:

  • 管理者ログイン

  • 登録の無効化

  • 医師モデルとCRUDサービス

  • OAuthスコープ承認

  • MCPツールの権限強制

  • トークン失効

ChatGPTの接続

サーバーが公開する認可URLを使用します:

  • /.well-known/oauth-authorization-server

  • /.well-known/oauth-protected-resource

  • /oauth/token

  • /mcp

一般的なフロー:

  1. ChatGPTがOAuthメタデータを検出します。

  2. ChatGPTがMCPリソースの認可を要求します。

  3. ブラウザが管理者ログイン画面にリダイレクトします。

  4. 管理者が権限を確認し、Allow & Connectをクリックします。

  5. ChatGPTがコードをトークンと交換します。

  6. ChatGPTがベアラートークンを使用してMCPツールを呼び出します。

デプロイ

このアプリは単一オリジンです: Expressが/api、/oauth、/mcp、OAuthディスカバリ、Reactビルドを提供します。

Vercel

このリポジトリにはvercel.jsonとapi/index.jsがすでに含まれています。VercelはExpressアプリを1つのサーバーレス関数として実行し、すべてのパスをそれに書き換えます。

1. MongoDB Atlas

  1. クラスターを作成します(無料のM0で十分です)。

  2. データベースユーザーを作成します。

  3. ネットワークアクセス: Vercelが接続できるように0.0.0.0/0を許可します(必要に応じてVercelのIPを追加しても構いません)。

  4. 接続文字列をコピーします。例:

mongodb+srv://USER:PASSWORD@cluster0.xxxxx.mongodb.net/mcpcontroller?retryWrites=true&w=majority

2. プロジェクトのデプロイ

  • このリポジトリをGitHubにプッシュします。

  • Vercelでリポジトリをインポートします。

  • Framework Preset: Other(そのままにします)。vercel.jsonがインストールとビルドを設定します。

  • Root Directory: リポジトリのルートのままにします(clientやserverには設定しないでください)。

  • Node.jsバージョン: 20.x以降。

3. Vercelでの環境変数

Project → Settings → Environment Variables。Production(プレビューURLを使用する場合はPreviewも)に設定します。

名前

例

備考

NODE_ENV

production

Vercelが通常自動で設定します。

APP_URL

https://your-app.vercel.app

末尾スラッシュなし。ライブオリジンと一致する必要があります。

API_URL

https://your-app.vercel.app

VercelではAPP_URLと同じ値。

MONGODB_URI

mongodb+srv://…/mcpcontroller

Atlas URI。

ADMIN_EMAIL

your admin email

同意UIへのログインに使用されます。

ADMIN_PASSWORD

a strong password

ログイン時に比較されます。ブラウザには送信されません。

JWT_SECRET

long random string

セッションクッキーの署名。例の値は使用しないでください。

JWT_EXPIRES_IN

7d

任意。

AUTH_CODE_TTL_SECONDS

120

任意。

ACCESS_TOKEN_TTL_SECONDS

3600

任意。

REFRESH_TOKEN_TTL_SECONDS

2592000

任意。

MCP_SERVER_NAME

MCPController

任意。

MCP_SERVER_VERSION

1.0.0

任意。

ADMIN_PASSWORDやJWT_SECRETをReactアプリに入れないでください。クライアントは/apiとのみ通信します。

後でカスタムドメインを追加する場合は、APP_URLとAPI_URLをhttps://your-domain.comに変更して再デプロイします。

JWT_SECRETは次のように生成します:

node -e "console.log(require('crypto').randomBytes(48).toString('hex'))"

4. 初回デプロイとシード

  1. デプロイします。

  2. https://your-app.vercel.app/api/healthを開きます — { "ok": true, ... }が表示されるはずです。

  3. 自分のマシンから、Atlasを指してMongoDBにシードします(Vercelのサーバーレス関数からではありません):

# In the project root, temporarily set MONGODB_URI to the Atlas URI in .env
npm run seed

シードは管理者ユーザー行、サンプル医師、ローカルMCP Inspectorクライアントを作成します。その後、ライブサイトでADMIN_EMAIL / ADMIN_PASSWORDでログインします。

5. ChatGPTの接続

デプロイされたオリジンを使用します:

  • https://your-app.vercel.app/.well-known/oauth-authorization-server

  • https://your-app.vercel.app/.well-known/oauth-protected-resource

  • https://your-app.vercel.app/mcp

ChatGPT(またはMCP Inspector)で、そのMCP URLを追加します。ChatGPTは同じドメインでログイン+同意画面を開き、その後Bearerトークンで/mcpを呼び出します。

CLIデプロイ(任意)

npm i -g vercel
vercel login
vercel env pull   # optional: sync env locally
vercel --prod

最初の本番デプロイ後、プレースホルダーを使用した場合はURLをAPP_URLとAPI_URLにコピーし、OAuthメタデータが実際のオリジンを指すように再デプロイします。

セキュリティに関する注意事項

  • ADMIN_PASSWORDやJWT_SECRETをブラウザに公開しないでください。

  • OAuthトークンはデータベースでハッシュ化して保持します。

  • 管理者がChatGPTに実際に使用させたいスコープのみを承認します。

  • 接続を信頼すべきでなくなった場合はアクセスを失効させます。

  • 管理者ログインはChatGPTを認可し医師データを管理するためだけに存在します。公開サインアップフローはありません。

シードデータ

シードスクリプトは以下を作成します:

  • サンプル医師

  • ローカルインスペクター用のサンプルOAuthクライアント

デモユーザーを作成したり、管理者認証情報をハードコードしたりはしません。

Related MCP Connectors

Related MCP Servers