mcpField
M
MedRecPro Drug Label Server

MedRecPro Drug Label Server

リモート
medrecpro.comヘルスケア412 週間前に更新
リポジトリ公式サイト

MedRecPro Drug Label Server について

MedRecPro Drug Label Serverは、MCPクライアントとMedRecPro Web APIをつなぐOAuth 2.1ゲートウェイです。MedRecProアプリにアクセスするクライアントを対象とし、READMEには通信方式と認証構成が記載されていますが、薬剤ラベル検索ツールの説明はありません。

主な機能

  1. 01OAuth 2.1認証ゲートウェイ
  2. 02Streamable HTTPによるMCP通信
  3. 03GoogleとMicrosoftでのサインイン
  4. 04ヘルスチェックと技術ドキュメントのエンドポイント

活用シーン

  1. 01MCPクライアントをMedRecPro Web APIに接続
  2. 02GoogleまたはMicrosoft経由でクライアントを認証
  3. 03サービス状態の確認とエンドポイント文書の参照

MCP 対応

`/mcp`でMCP Streamable HTTPエンドポイントを提供し、MCPクライアントとMedRecPro Web APIの間でOAuth 2.1ゲートウェイとして動作します。READMEには公開するMCPツールの一覧がありません。

設定

リモートサーバーはインストール不要です。クライアントを選んで設定をコピーするか、ワンクリックで導入できます。

エンドポイントhttps://www.medrecpro.com/mcp
インストールコマンドをコピー
Claude CodeTerminal
Cursor.cursor/mcp.json
VS Code.vscode/mcp.json
Claude Desktopclaude_desktop_config.json
Windsurf~/.codeium/windsurf/mcp_config.json

コマンドはターミナルで実行し、JSON は各クライアントの MCP 設定に貼り付けて再起動します。認可が必要なサーバーは初回接続時にログインを求めます。

ツール

詳細

MedRecPro MCP サーバー

MedRecPro アプリケーション用の MCP(Model Context Protocol)サーバーです。MCP クライアント(Claude など)と MedRecPro Web API の間で、OAuth 2.1 ゲートウェイとして動作します。

バージョン: 1.0.0 ランタイム: ASP.NET Core 8.0 本番 URL: https://www.medrecpro.com/mcp

アーキテクチャ

                             Azure App Service: "MedRecPro" (Windows, IIS)
                            +--------------------------------------------------+
                            |                                                  |
+------------------+        |  /          site\wwwroot       MedRecProStatic   |
|  Claude / MCP    |  HTTPS |  /api       site\wwwroot\api   MedRecPro API     |
|  Client          |------->|  /mcp       site\wwwroot\mcp   MedRecProMCP      |
+------------------+        |                                                  |
        |                   +--------------------------------------------------+
        v                                    |
+------------------+                         v
|  Cloudflare      |                +------------------+
|  (CDN/WAF/DNS)   |                |  Azure Key Vault |
+------------------+                |  (medrecprovault)|
                                    +------------------+

MCP サーバーは、メインの MedRecPro UI および API と同じ Azure App Service 上で、/mcp に IIS 仮想アプリケーションとして実行されます。IIS はパスベースのルーティングを処理し、3 つの個別の ASP.NET Core プロセスに振り分けます。

仮想パス物理パスプロジェクト用途
/site\wwwrootMedRecProStaticUI/静的コンテンツ
/apisite\wwwroot\apiMedRecProWeb API
/mcpsite\wwwroot\mcpMedRecProMCPMCP サーバー(このプロジェクト)

エンドポイント

IIS 仮想アプリケーションにより、すべてのエンドポイントの外部パスには /mcp が付加されます。

外部 URLメソッド説明
/mcpPOSTMCP Streamable HTTP トランスポート(JSON-RPC)
/mcp/healthGETヘルスチェック(JSON ステータスを返します)
/mcp/docsGETHTML 技術ドキュメントページ
/mcp/getting-startedGETHTML はじめ方ページ(ディレクトリ掲載用のユーザー向けページ)
/mcp/docs/images/{filename}GET埋め込みスクリーンショット画像(PNG)を提供します
/mcp/.well-known/oauth-protected-resourceGET保護対象リソースメタデータ(RFC 9728)
/mcp/.well-known/oauth-authorization-serverGET認可サーバーメタデータ(RFC 8414)
/mcp/oauth/authorizeGETOAuth 認可エンドポイント
/mcp/oauth/tokenPOSTトークン交換エンドポイント
/mcp/oauth/registerPOST動的クライアント登録(RFC 7591)
/mcp/oauth/callback/googleGETGoogle OAuth コールバック
/mcp/oauth/callback/microsoftGETMicrosoft OAuth コールバック

注: GET /mcp は HTTP 405(Method Not Allowed)を返します。これは正しい動作です。MCP トランスポートが受け付けるのは POST リクエストのみです。ブラウザーからアクセスできるページには、/mcp/docs(技術ドキュメント)または /mcp/getting-started(ユーザー向けガイド)を使用してください。

認証フロー

1. Claude sends POST to /mcp (unauthenticated)
2. Server returns 401 with WWW-Authenticate header pointing to PRM
3. Claude fetches /mcp/.well-known/oauth-protected-resource
4. Claude fetches /mcp/.well-known/oauth-authorization-server
5. Claude registers via /mcp/oauth/register (Dynamic Client Registration)
6. Claude redirects user to /mcp/oauth/authorize?provider=google
7. User authenticates with Google/Microsoft
8. Provider redirects to /mcp/oauth/callback/{provider}
9. MCP server resolves upstream IdP email to numeric DB user ID via POST /api/users/resolve-mcp
   (auto-provisions user if they don't exist in the database)
10. MCP server issues authorization code with numeric `sub` claim (standard JWT name), redirects to Claude
11. Claude exchanges code for tokens via /mcp/oauth/token
12. Claude sends authenticated POST to /mcp with Bearer MCP JWT
13. MCP server forwards MCP JWT to MedRecPro API for each tool call (McpBearer auth scheme)

ユーザー解決と自動プロビジョニング

OAuth コールバック(ステップ 9)では、MCP サーバーが上流の ID プロバイダーの識別子(Google の sub/Microsoft の GUID)を MedRecPro データベースの数値ユーザー ID にマッピングする必要があります。API の getEncryptedIdFromClaim() メソッドは、数値の NameIdentifier クレームを想定しています。この解決処理がないと、すべての API 呼び出しが 401 で失敗します。

仕組み:

  1. OAuthEndpoints.cs が上流 IdP のクレームからメールアドレス、表示名、プロバイダーを抽出します
  2. UserResolutionService が一時的な MCP JWT を生成し、POST /api/users/resolve-mcp を呼び出します
  3. API の UsersController.ResolveMcpUser() がメールアドレスでユーザーを検索します:
    • ユーザーが存在する場合: 暗号化されたデータベースのユーザー ID を返します
    • ユーザーが存在しない場合: 新しいユーザーレコードを自動プロビジョニングし(AuthController.createUserForExternalLogin() のデフォルトに合わせて、EmailConfirmed=true、Timezone="UTC"、Locale="en-US"、パスワードなし)、暗号化された ID を返します
  4. UserResolutionService が、共有の Security:DB:PKSecret を使用して StringCipher によって暗号化 ID を復号します
  5. OAuthEndpoints.cs が上流の NameIdentifier クレームを数値のデータベースユーザー ID に置き換えます
  6. トークン作成時に McpTokenService.normalizeClaimType() が ClaimTypes.NameIdentifier を標準の JWT sub クレームに変換し、二重マッピングを防ぐために OutboundClaimTypeMap がクリアされます
  7. MCP JWT が数値ユーザー ID を sub クレームとして発行され、すべての API 呼び出しが成功するようになります

主要なアーキテクチャ:

  • TokenForwardingHandler は MCP JWT を API に直接転送します(上流の Google/Microsoft トークンではありません)。API の McpBearer 認証スキームが、これらの MCP 署名付き JWT を検証します。
  • MCP サーバーと API はどちらも、ユーザー ID の StringCipher による暗号化/復号に Azure Key Vault の Security:DB:PKSecret を共有して使用します。
  • UserResolutionService は、解決処理中にトークン転送が循環するのを防ぐため、専用の "MedRecProApiDirect" という名前付き HttpClient(TokenForwardingHandler なし)を使用します。
  • クレームの正規化: McpTokenService は、トークン作成前に .NET の ClaimTypes URI を標準の JWT 短縮名(sub、name、email、given_name、family_name)に正規化します。両方の JWT ハンドラーで MapInboundClaims = false を設定するため、読み戻したときにクレームは短縮名のまま保持されます。API の ClaimHelper は、ClaimTypes.NameIdentifier(Cookie 認証)と "sub"(MCP JWT 認証)の両方からユーザー ID を解決します。

コンパイラーディレクティブ(#if DEBUG)

ルートパスではコンパイラーディレクティブを使用して、IIS による仮想アプリケーションパスの除去に対応します。これは、MedRecPro API プロジェクトの ApiControllerBase と同じパターンに従っています。

問題: IIS は、アプリに転送する前にリクエストから /mcp プレフィックスを除去します。www.medrecpro.com/mcp/oauth/authorize へのリクエストは、Kestrel には /oauth/authorize として届きます。ルートではこの点を考慮する必要があります。

コンポーネントDEBUG(ローカル開発)RELEASE(Azure/IIS)
MCP トランスポートMapMcp("/mcp")MapMcp("/")
ヘルスチェックGET /GET /health
ドキュメントGET /mcp/docsGET /docs
はじめにGET /mcp/getting-startedGET /getting-started
画像配信GET /mcp/docs/images/{filename}GET /docs/images/{filename}
OAuth グループ/mcp/oauth/oauth
Well-known メタデータ/mcp/.well-known/*/.well-known/*
PRM リダイレクト/mcp/.well-known/oauth-protected-resource が SDK パスにリダイレクト不要(IIS が処理)

コンパイラーディレクティブがあるファイル:

  • Program.cs - MCP トランスポート、ヘルスチェック、ドキュメント、はじめに、画像配信、PRM リダイレクト
  • Endpoints/OAuthEndpoints.cs - OAuth ルートグループのプレフィックス
  • Endpoints/OAuthMetadataEndpoints.cs - Well-known メタデータのパス

設定駆動(ディレクティブ不要):

  • OAuth コールバック URL - 実行時に McpServer:ServerUrl から構築
  • OAuth メタデータドキュメントの内容 - 実行時に McpServer:ServerUrl から構築
  • 保護リソースメタデータ - 実行時に McpServer:ServerUrl から構築

セットアップガイド

前提条件
  • .NET 8.0 SDK
  • 以下を備えた Azure サブスクリプション:
    • App Service(Windows、IIS)— MedRecPro と共有
    • Key Vault(medrecprovault)
    • Application Insights(任意)
  • medrecpro.com ドメインを持つ Cloudflare アカウント
  • OAuth 2.0 認証情報を持つ Google Cloud Console プロジェクト
  • Microsoft Entra ID アプリ登録
1. ローカル開発環境のセットアップ
クローンと復元
git clone <repo-url>
cd MedRecProMCP
dotnet restore
ユーザーシークレットの設定
dotnet user-secrets init
dotnet user-secrets set "McpServer:JwtSigningKey" "<min-32-char-key>"
dotnet user-secrets set "Jwt:Key" "<min-32-char-key>"
dotnet user-secrets set "Jwt:Issuer" "http://localhost:5233/mcp"
dotnet user-secrets set "Jwt:Audience" "http://localhost:5233/mcp"
dotnet user-secrets set "Jwt:ExpirationMinutes" "60"
dotnet user-secrets set "Jwt:UpstreamTokenEncryptionKey" "<32-char-aes-key>"
dotnet user-secrets set "Authentication:Google:ClientId" "<google-client-id>"
dotnet user-secrets set "Authentication:Google:ClientSecret" "<google-client-secret>"
dotnet user-secrets set "Authentication:Microsoft:ClientId" "<microsoft-app-id>"
dotnet user-secrets set "Authentication:Microsoft:ClientSecret:Dev" "<microsoft-client-secret>"
dotnet user-secrets set "Authentication:Microsoft:TenantId" "<azure-tenant-id>"
dotnet user-secrets set "Security:DB:PKSecret" "<encryption-key-must-match-api>"
ローカルで実行
dotnet run

サーバーは http://localhost:5233 で実行されます。DEBUG モードでは、エンドポイントに /mcp プレフィックスが付きます:

2. Azure App Service のセットアップ
仮想アプリケーションの追加

Azure Portal で:

  1. App Service "MedRecPro" > Configuration > Path mappings に移動します
  2. "+ Add virtual application or directory" をクリックします
  3. 以下を設定します:
    • Virtual path: /mcp
    • Physical path: site\wwwroot\mcp
    • Type: Application にチェックを入れます
  4. Save をクリックします
Key Vault シークレット

Azure Key Vault(medrecprovault)に以下のシークレットが存在することを確認してください。両方のアプリが同じ Key Vault を使用するため、これらは MedRecPro API と共有されます:

シークレット名説明
McpServer--JwtSigningKeyMCP トークン用の JWT 署名キー(32 文字以上)
Jwt--KeyJWT 署名キー
Jwt--IssuerJWT 発行者クレーム
Jwt--AudienceJWT オーディエンスクレーム
Jwt--ExpirationMinutesトークンの有効期限(例:60)
Jwt--UpstreamTokenEncryptionKeyアップストリームトークン用 AES 暗号化キー
Authentication--Google--ClientIdGoogle OAuth クライアント ID
Authentication--Google--ClientSecretGoogle OAuth クライアントシークレット
Authentication--Microsoft--ClientIdMicrosoft Entra アプリ ID
Authentication--Microsoft--ClientSecret--ProdMicrosoft クライアントシークレット(本番環境)
Authentication--Microsoft--TenantIdAzure AD テナント ID
Security--DB--PKSecretユーザー ID の暗号化/復号に使用する共有暗号化キー(API と一致している必要があります)

注: Key Vault では区切り文字として -- を使用します。ASP.NET Core はこれらを構成内で : に変換します(例:Jwt--Key は Jwt:Key になります)。

マネージド ID

App Service には、Key Vault シークレットに対する Get および List 権限を持つ、システム割り当てのマネージド ID が必要です。MCP 仮想アプリケーションは API と同じ App Service を共有するため、既存のマネージド ID はすでにアクセス権を持っているはずです。

3. OAuth プロバイダーの構成
Google Cloud Console
  1. Google Cloud Console > APIs & Services > Credentials に移動します
  2. OAuth 2.0 クライアント ID を編集します
  3. 承認済みリダイレクト URI を追加します:
    • https://www.medrecpro.com/mcp/oauth/callback/google(本番環境)
    • http://localhost:5233/mcp/oauth/callback/google(開発環境)
Microsoft Entra ID
  1. Azure Portal > Microsoft Entra ID > App registrations に移動します
  2. アプリを選択し、Authentication に移動します
  3. リダイレクト URI を追加します:
    • https://www.medrecpro.com/mcp/oauth/callback/microsoft(本番環境)
    • http://localhost:5233/mcp/oauth/callback/microsoft(開発環境)
4. Cloudflare の構成

MCP サーバーは同じドメイン(www.medrecpro.com)で実行されるため、DNS の変更は不要です。以下のルールを設定します:

キャッシュルール — /mcp のキャッシュをバイパス

Caching > Cache Rules > Create rule

  • Rule name: Bypass cache for MCP server
  • When: Hostname が www.medrecpro.com と等しく、かつ URI Path が /mcp で始まる
  • Then: Cache eligibility:Bypass cache
変換ルール — SSE のレスポンスバッファリングを無効にする

ルール > 変換ルール > レスポンスヘッダーを変更 > ルールを作成

  • ルール名: Disable buffering for MCP SSE
  • 条件: ホスト名が www.medrecpro.com と等しく、かつ URI パスが /mcp で始まる
  • 処理: 静的ヘッダー X-Accel-Buffering を no に設定

これにより、MCP Streamable HTTP トランスポートで使用される Server-Sent Events が Cloudflare によってバッファリングされなくなります。

WAF ルール(任意)

/mcp または /mcp/oauth/* への POST リクエストをブロックする可能性のある既存の WAF ルールがある場合にのみ必要です。WAF にカスタムルールがない場合は、この手順を省略できます。

5. デプロイ
Visual Studio から発行
  1. ソリューション エクスプローラーで MedRecProMCP を右クリックし、発行 を選択します
  2. "MedRecProMCP - Web Deploy" プロファイルを選択します
  3. 設定を確認します:
    • 構成:Release
    • ターゲット フレームワーク:net8.0
    • デプロイ モード:フレームワーク依存
  4. 発行 をクリックします

発行プロファイルは、<DeployIisAppPath>MedRecPro/mcp</DeployIisAppPath> の設定を使用して site\wwwroot\mcp にデプロイします。

CLI から発行
dotnet publish -c Release -o ./publish

次に、Azure CLI または zip デプロイを使用して、/mcp 仮想アプリケーションパスにデプロイします。

6. 検証

デプロイ後、各エンドポイントを確認します:

# Health check — should return JSON with status "running"
curl https://www.medrecpro.com/mcp/health

# MCP transport — should return 405 (GET not allowed, POST only)
curl -i https://www.medrecpro.com/mcp

# OAuth Authorization Server Metadata — should return JSON
curl https://www.medrecpro.com/mcp/.well-known/oauth-authorization-server

# Protected Resource Metadata — should return JSON
curl https://www.medrecpro.com/mcp/.well-known/oauth-protected-resource

# Documentation page — should return HTML
curl https://www.medrecpro.com/mcp/docs

# Getting-started page — should return HTML with screenshots
curl https://www.medrecpro.com/mcp/getting-started

# Screenshot images — should return PNG image data
curl -I https://www.medrecpro.com/mcp/docs/images/MCP-Adverse-Example.PNG

# Main site still works
curl https://www.medrecpro.com
curl https://www.medrecpro.com/api

構成リファレンス

appsettings.json(基本)

すべての環境で共有される、シークレット以外の構成です。

キー説明デフォルト
McpServer:ServerUrlMCP サーバーのベース URL(/mcp を含む)https://www.medrecpro.com/mcp
McpServer:ServerName表示名MedRecPro MCP Server
McpServer:ScopesSupportedOAuth スコープopenid, profile, email, mcp:tools, mcp:read, mcp:write
McpServer:EnableDynamicClientRegistrationRFC 7591 による登録を許可true
McpServer:MaxRegisteredClients動的クライアントの最大数1000
McpServer:ClientRegistrationExpirationHoursクライアントの TTL24
MedRecProApi:BaseUrlMedRecPro API の URLhttps://www.medrecpro.com/api
MedRecProApi:TimeoutSecondsHTTP クライアントのタイムアウト30
MedRecProApi:RetryCountHTTP リトライ回数3
Security:DB:PKSecretStringCipher 用の共有暗号化キー(API と一致させる必要があります)(Key Vault)
KeyVaultUrlAzure Key Vault の URL(基本設定では空、Production で設定)
appsettings.Development.json
キー上書き値
McpServer:ServerUrlhttp://localhost:5233/mcp
MedRecProApi:BaseUrlhttp://localhost:5093/api
MedRecProApi:ValidateSslCertificatefalse
appsettings.Production.json
キー上書き値
McpServer:ServerUrlhttps://www.medrecpro.com/mcp
MedRecProApi:BaseUrlhttps://www.medrecpro.com/api
KeyVaultUrlhttps://medrecprovault.vault.azure.net/

プロジェクト構成

MedRecProMCP/
  Program.cs                          # App startup, DI, middleware, endpoint mappings
  MedRecProMCP.csproj                 # Project file (.NET 8.0)
  MedRecProMCP.slnx                   # Solution file
  MedRecProMCP.http                   # HTTP request test file
  web.config                          # IIS configuration (OutOfProcess hosting)
  server.json                         # MCP registry metadata (see MCP Registry below)
  Documentation.md                    # Anthropic Connectors Directory submission doc
  appsettings.json                    # Base configuration
  appsettings.Development.json        # Local dev overrides
  appsettings.Production.json         # Azure production overrides
  Configuration/
    McpServerSettings.cs              # MCP server config model
    MedRecProApiSettings.cs           # API client config model
    JwtSettings.cs                    # JWT config model
    OAuthProviderSettings.cs          # OAuth provider config model (Google, Microsoft)
  Endpoints/
    OAuthEndpoints.cs                 # OAuth authorize, token, register, callbacks
    OAuthMetadataEndpoints.cs         # .well-known metadata endpoints
  Services/
    IMcpTokenService.cs               # Token service interface
    McpTokenService.cs                # JWT token generation and validation
    IOAuthService.cs                  # OAuth service interface
    OAuthService.cs                   # OAuth flow orchestration
    IClientRegistrationService.cs     # Client registration interface
    ClientRegistrationService.cs      # Dynamic Client Registration (RFC 7591)
    IPkceService.cs                   # PKCE service interface
    PkceService.cs                    # PKCE implementation
    IPersistedCacheService.cs         # Persisted cache interface
    FilePersistedCacheService.cs      # File-based persistent cache (PKCE, registrations)
    MedRecProApiClient.cs             # Typed HTTP client for MedRecPro API
    IUserResolutionService.cs         # User resolution service interface
    UserResolutionService.cs          # Resolves upstream IdP email to numeric DB user ID
  Handlers/
    TokenForwardingHandler.cs         # Forwards MCP JWT to API (DelegatingHandler)
  Helpers/
    StringCipher.cs                   # AES encryption/decryption (copy from API for user ID handling)
  Models/
    AiAgentDtos.cs                    # AI/Claude integration models
    WorkPlanModels.cs                 # Work plan and execution models
  Tools/
    DrugLabelTools.cs                 # MCP tools for drug labels, patent expiration (annotated)
    UserTools.cs                      # MCP tools for user/account operations (annotated)
  Templates/
    McpDocumentation.html             # Embedded HTML technical documentation template
    McpGettingStarted.html            # Embedded HTML getting-started page (user-facing)
    Images/
      MCP-Adverse-Example.PNG         # Screenshot: warnings/adverse effects lookup
      MCP-Authentication-Example.PNG  # Screenshot: user profile/authentication status
      MCP-Full-Label-Example.PNG      # Screenshot: complete label export
      MCP-Indication-Example.PNG      # Screenshot: drug indications lookup
      MCP-Starting-Dose-Example.PNG   # Screenshot: dosage information lookup
  PowerShell/
    test-mcp.ps1                      # MCP endpoint test script
    test-mcp-detailed.ps1             # Detailed MCP test with verbose output
    test-mcp-root.ps1                 # Root endpoint test script
  Properties/
    launchSettings.json               # Local development profiles
    PublishProfiles/
      MedRecProMCP - Web Deploy.pubxml  # Azure deployment profile
  Docs/
    DeploymentGuide.md                # Legacy deployment guide (subdomain approach)

Claude.ai コネクターとの統合

このセクションでは、Claude.ai の「設定 > コネクター」で MCP サーバーをカスタムコネクターとして接続する手順について説明します。IIS 仮想アプリケーション、Cloudflare、Azure のアーキテクチャに固有の数多くの障害に直面しながら、複数のセッションにわたって取り組みました。

Anthropic コネクターディレクトリへの提出

Anthropic コネクターディレクトリへの提出資料:

  • Documentation.md — Anthropic のテンプレートに沿った提出用ドキュメント(説明、機能、セットアップ、スクリーンショット付きの例)
  • /mcp/getting-started — ディレクトリの掲載ページからリンクされる、ユーザー向け HTML ページ
  • ツールのアノテーション — 5 つすべてのツールに ReadOnly、Destructive、OpenWorld の安全性アノテーションを含めています
  • 認証 — PKCE を使用した OAuth 2.1 で、動的クライアント登録(RFC 7591)をサポートしています。特別なアカウントは不要です。レビュー担当者は Google または Microsoft の任意のアカウントで認証でき、自動的にプロビジョニングされます。
接続ステータス
コンポーネントステータス
OAuth 2.1 フロー(PKCE S256)動作中
MCP セッションの確立(initialize)動作中
ツールの一覧表示(tools/list)動作中
ツールの実行(tools/call)動作中
下流 API 呼び出し(MCP -> MedRecPro API)動作中
MCP ユーザーの解決(メールアドレス -> 数値の DB ID)動作中
MCP ユーザーの自動プロビジョニング(新規ユーザー)動作中
JWT クレームの正規化(sub、name、email)動作中
UsersController [Authorize(Policy = "ApiAccess")]動作中
ツールの安全性アノテーション

7 つのツールすべてに、[McpServerTool] 属性のプロパティを使用して MCP の安全性アノテーションが宣言されています(ModelContextProtocol SDK v0.7.0-preview.1 でサポート)。

ツールタイトル読み取り専用破壊的オープンワールド
search_drug_labels医薬品ラベルを検索truefalsefalse
export_drug_label_markdown医薬品ラベルをエクスポートtruefalsefalse
search_expiring_patents期限切れ間近の特許を検索truefalsefalse
search_by_pharmacologic_class薬理クラスで検索truefalsefalse
get_my_profile自分のプロフィールを取得truefalsefalse
get_my_activity自分のアクティビティを取得truefalsefalse
get_my_activity_by_date_range期間を指定してアクティビティを取得truefalsefalse

アノテーションの理由:

  • すべてのツールは読み取り専用です。どのツールもデータを変更しません
  • すべてのツールで OpenWorld = false を使用しています。すべてのデータは、コンソールアプリケーション経由で登録された MedRecPro データベース内に完結しているためです
発生した問題と修正

統合中に以下の問題が順番に発生しました。次の問題を確認するには、それぞれを解決する必要がありました。

1. PKCE 検証の失敗

症状: OAuth トークンの交換が PKCE の不一致により失敗しました。 根本原因: PKCE の検証子とチャレンジのペアが、認可フロー全体で正しく保存および照合されていませんでした。 修正: PkceService.cs の PKCE 保存および検証ロジックを修正しました。

2. ディスカバリーエンドポイントが 302 リダイレクトを返す

症状: Claude の MCP SDK が /.well-known/oauth-protected-resource および /.well-known/oauth-authorization-server に対して JSON ではなく 302 リダイレクトを受信しました。 根本原因: IIS のパスベースルーティングと /mcp の仮想アプリケーションにより、ディスカバリー URL の解決で問題が発生しました。MCP SDK はドメインルートの /.well-known/* を想定していますが、MCP サーバーは /mcp 配下のリクエストのみを処理します。 修正: MedRecProStatic/Program.cs(ルートサイト)に well-known エンドポイントを直接追加し、OAuth メタデータを静的な JSON レスポンスとして返すようにしました。これにより、リダイレクトを完全に回避できます。

3. MCP トランスポートに [Authorize] がない

症状: 認証なしで Claude が接続でき、401 チャレンジが送信されませんでした。 根本原因: MapMcp() エンドポイントに .RequireAuthorization() がありませんでした。 修正: Program.cs の MapMcp("/") 呼び出しに .RequireAuthorization() を追加しました(RELEASE 構成)。

4. MCP トランスポートの [AllowAnonymous]

症状: .RequireAuthorization() を追加しても、MCP トランスポートは 401 を返しませんでした。 根本原因: MCP SDK のデフォルトトランスポートミドルウェアが、内部で [AllowAnonymous] を適用していました。 修正: McpAuthenticationHandler チャレンジスキームを使用し、未認証のリクエストに resource_metadata URI を含む WWW-Authenticate ヘッダーが返されるようにしました。

5. IIS が 401 を HTML エラーページに置き換える

症状: Claude は WWW-Authenticate ヘッダーを含む JSON の 401 レスポンスではなく、HTML エラーページを受信しました。 根本原因: IIS は HTTP エラーレスポンスを傍受し、独自の HTML ページに置き換えます。 修正: MedRecProStatic(ルートサイト)と MedRecProMCP の両方の web.config に <httpErrors existingResponse="PassThrough" /> を追加しました。ルートサイトの設定は子の仮想アプリケーションに継承されるため、特に重要です。

6. 401 応答に含まれる resource_metadata URL が誤っている

症状: Claude が保護対象リソースメタデータ(PRM)エンドポイントを見つけられませんでした。 根本原因: WWW-Authenticate ヘッダーの resource_metadata URI が誤ったパスを指していました。 修正: McpAuthenticationHandler の構成で ResourceMetadataUri を {ServerUrl}/.well-known/oauth-protected-resource に明示的に設定しました。

7. PRM エンドポイントが 404 を返す

症状: URL を修正した後、PRM エンドポイントが 404 を返しました。 根本原因: ルート登録の順序と IIS によるパスの除去により、エンドポイントがマッピングされていませんでした。 修正: OAuthMetadataEndpoints.cs に正しいルーティングで PRM エンドポイントの登録を明示的に追加しました。

8. Cloudflare の「Manage AI Bots」WAF ルールによる Claude のブロック

症状: Claude のリクエストがサーバーに到達しませんでした(Cloudflare が 403 を返しました)。 根本原因: Cloudflare の管理対象 WAF ルール「Block AI Bots」が、Claude-User(Anthropic のクローラーのユーザーエージェント)からのすべてのリクエストをブロックしていました。AI Crawl Control ダッシュボードには、ブロックされたリクエストが 149 件、許可されたリクエストが 0 件と表示されていました。 修正(Cloudflare ダッシュボード):

  1. Security > Settings > Block AI Bots Scope — 「広告のあるホスト名のみブロック」に変更
  2. Security > AI Crawl Control > Crawlers — Claude-User(Anthropic)を許可に設定
9. JWT オーディエンスの検証に失敗(IDX10214)

症状: IDX10214: Audience validation failed. Audiences: 'https://www.medrecpro.com/mcp'. Did not match: validationParameters.ValidAudience: 'MedRecUsers' 根本原因: McpTokenService はオーディエンスを ServerUrl(https://www.medrecpro.com/mcp)に設定したトークンを発行しますが、JWT Bearer ハンドラーは MedRecUsers(Jwt:Audience の構成値)のみを受け入れていました。 修正: 単一値の ValidAudience を ValidAudiences(配列)に変更し、jwtSettings.Audience と mcpSettings.ServerUrl.TrimEnd('/') の両方を受け入れるようにしました。

10. JWT 発行者の検証に失敗(IDX10205)

症状: IDX10205: Issuer validation failed. Issuer: 'https://www.medrecpro.com/mcp'. Did not match: validationParameters.ValidIssuer: 'MedRecPro' 根本原因: オーディエンスの場合と同じ二重トークンの問題です。McpTokenService は発行者に ServerUrl を使用しますが、JWT ハンドラーは MedRecPro のみを受け入れていました。 修正: 単一値の ValidIssuer を ValidIssuers(配列)に変更し、jwtSettings.Issuer と mcpSettings.ServerUrl.TrimEnd('/') の両方を受け入れるようにしました。

11. Cloudflare の Bot Fight Mode による下流 API 呼び出しのブロック

症状: MCP ツールは実行されましたが、403 を返しました。MCP サーバーから https://www.medrecpro.com/api/... への HTTP 呼び出しがブロックされていました。 根本原因: MCP サーバー(Azure 上で実行)は、パブリック API URL にアウトバウンド HTTP リクエストを送信します。これらのリクエストは Cloudflare を経由し、空の User-Agent ヘッダーを持つ Azure の IP アドレスから送信されたため、Bot Fight Mode によって検知されました。 修正(2 部構成):

  1. コード — Program.cs の両方の HttpClient 登録に User-Agent: MedRecProMCP/1.0 (Internal-API-Client) ヘッダーを追加しました
  2. Cloudflare — WAF カスタムルールでは Bot Fight Mode をスキップできませんが、リクエストにIP Access Ruleが一致すれば発動しません。Azure App Service のアウトバウンド IP 32 個すべてに対して、アクションを Allow に設定した IP Access Rules を追加しました:
    # Get all possible outbound IPs for the App Service
    az webapp show --resource-group <rg> --name <app> \
      --query possibleOutboundIpAddresses --output tsv
    
    # Add each IP as a Cloudflare IP Access Rule (Allow)
    # Use Cloudflare API with Global API Key:
    for ip in $IPS; do
      curl -s -X POST \
        "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/firewall/access_rules/rules" \
        -H "X-Auth-Email: $EMAIL" \
        -H "X-Auth-Key: $API_KEY" \
        -H "Content-Type: application/json" \
        --data "{\"mode\":\"whitelist\",\"configuration\":{\"target\":\"ip\",\"value\":\"$ip\"},\"notes\":\"Azure App Service outbound IP\"}"
    done
    
12. Azure SQL Database のコールドスタートによるタイムアウト

症状: アイドル状態の後、最初のツール呼び出しが Database 'MedRecProDB' is not currently available または Execution Timeout Expired(コマンドタイムアウト 30 秒)で失敗します。 根本原因: Azure SQL Serverless は、一定時間操作がないと自動的に一時停止します。再開に 15~30 秒以上かかり、HttpClient のタイムアウト(30 秒)と SQL コマンドのタイムアウト(30 秒)の両方を超過します。 ステータス: 既知の問題です。データベースがウォームアップすると、後続のリクエストは成功します。緩和策として、自動一時停止までの時間を延長する、UseSqlServer で EnableRetryOnFailure を有効にする、または MedRecProApi の設定で TimeoutSeconds を増やす方法があります。

13. JWT クレーム型のマッピング不一致(ツール呼び出し時に 401)

症状: OAuth ログインが成功して MCP JWT が生成された後、API にアクセスするすべてのツール呼び出しが 401 を返します。ログには [Auth] Token validated for user: unknown と表示され、getEncryptedIdFromClaim() が UnauthorizedAccessException: Unable to determine user ID from authentication context をスローします。 根本原因: JwtSecurityTokenHandler.OutboundClaimTypeMap は、JWT のシリアライズ時に ClaimTypes.NameIdentifier を "sub" に、ClaimTypes.Name を "unique_name" に暗黙的に変換します。API 側の getEncryptedIdFromClaim() は c.Type.Contains("NameIdentifier") を検索していましたが、これは "sub" と一致しませんでした。さらに、NameClaimType = "name" は "name" クレームを想定していましたが、JWT に含まれていたのは "unique_name" だったため、Identity.Name は null になっていました。 修正(3 つの対応):

  1. McpTokenService — トークンの作成前に ClaimTypes.* URI を標準の JWT 短縮名(sub、name、email、given_name、family_name)に明示的にマッピングする normalizeClaimType() を追加しました。二重マッピングを防ぐため、OutboundClaimTypeMap をクリアしました。
  2. 両方の JWT ハンドラー — MCP サーバーと API の McpBearer ハンドラーに MapInboundClaims = false を追加し、ClaimsPrincipal に読み込む際にクレームが元の短縮名を保持するようにしました。
  3. API のクレーム読み取り処理 — ClaimHelper.cs を作成し、ClaimTypes.NameIdentifier(Cookie 認証)と "sub"(MCP JWT)の両方からユーザー ID を解決できるようにしました。UsersController、AiController、AuthController、LabelController、RequireActorAttributeFilter、RequireUserRoleAttributeFilter、ActivityLogActionFilter、LogHelper に分散していた 9 か所の NameIdentifier 参照を、共通ヘルパーを使うように更新しました。
14. UsersController に [Authorize] がない(MCP ツール呼び出し時に 401)

症状: JWT クレームの正規化(Issue #13)を修正した後、MCP 側のログには [Auth] Token validated for user: Christopher Barnes と正しく表示されるようになりましたが、API のツール呼び出しは依然として 401 を返します。ClaimHelper.GetEncryptedUserIdOrThrow は、User.Claims が空のため例外をスローします。IIS のログには Logon User: Anonymous と表示されます。API 側からの [MCP Auth] ログはありません。 根本原因: UsersController には、クラスレベルにも個々のエンドポイントにも [Authorize] 属性がありませんでした(resolve-mcp を除く)。[Authorize] がないと、ASP.NET Core の JWT Bearer ハンドラーは McpBearer トークンに対して呼び出されず、リクエストは匿名として処理されて User.Claims が空になります。Identity ミドルウェアはすべてのリクエストでセッション Cookie から User.Claims を設定するため、Cookie 認証は [Authorize] がなくても機能していました。一方、JWT Bearer スキームでは、検証を実行するために明示的な [Authorize] が必要です。 修正: UsersController クラスに [Authorize(Policy = "ApiAccess")] を追加しました。ApiAccess ポリシー(Program.cs)は IdentityConstants.ApplicationScheme(Cookie)と "McpBearer"(JWT)の両方を受け入れるため、既存の Cookie 認証の動作を維持しながら、MCP リクエストで JWT ハンドラーが呼び出されるようになります。一般公開を維持する必要がある signup と authenticate のエンドポイントには [AllowAnonymous] を追加しました。また、SecurityTokenException のログ出力を暗黙的に抑制していた OnAuthenticationFailed ハンドラーも修正しました。

15. GetMyActivity / GetMyActivityByDateRange がサイレントに失敗する

症状: Issue #14 を修正した後、GetMyProfile は正常に 200 を返しますが、GetMyActivity と GetMyActivityByDateRange はすぐに完了し、アクティビティエンドポイントへの 2 回目の HTTP リクエストが発生しません。MCP ツールは Claude に {"error":"Could not determine user ID"} を返します。 根本原因(A — MCP 側): UserTools.cs は profile.TryGetProperty("encryptedId", ...) を呼び出しますが、API は Newtonsoft.Json と CamelCasePropertyNamesContractResolver を使用してシリアライズします。実際の JSON プロパティ名は "encryptedUserId"(キャメルケースで、元の検索キーでは「User」が抜けていました)です。大文字小文字を区別する TryGetProperty の検索が失敗するため、2 回目の API 呼び出しが行われません。 根本原因(B — API 側): UsersController.cs の GetUserActivity(452 行目)と GetUserActivityByDateRange(630 行目)では、if (!isSelf || !claimsUser.IsUserAdmin()) が使われていました。OR ではなく AND にすべきでした。この条件により、一般ユーザーが自分自身のアクティビティログを閲覧できませんでした。対象ユーザーであり、かつ管理者でもあるユーザーだけがチェックを通過できる状態でした。 修正: JSON プロパティ名のキャメルケースに合わせるため、UserTools.cs の "encryptedId" を "encryptedUserId" に(両方の箇所で)変更しました。UsersController.cs の両方の認可チェックで || を && に変更し、すべてのユーザーが自分自身のデータにアクセスでき、管理者は任意のユーザーのログにアクセスできるようにしました。

得られた教訓
  1. IIS の仮想アプリケーションはパスのプレフィックスを削除します。 /mcp/oauth/authorize へのリクエストは、Kestrel には /oauth/authorize として届きます。RELEASE ビルドでは、すべてのルートマッピングでこれを考慮する必要があります。#if DEBUG ディレクティブを使用してください。

  2. OAuth のディスカバリーはドメインのルートに配置する必要があります。 MCP SDK は /.well-known/* を MCP エンドポイントのパスではなく、ドメインを基準に解決します。これらのエンドポイントは MCP 仮想アプリケーションではなく、ルートサイト(MedRecProStatic)から提供してください。

  3. httpErrors existingResponse="PassThrough" は非常に重要です。 これがないと、IIS は OAuth チャレンジに必要な 401 レスポンスを HTML エラーページに置き換えます。子仮想アプリケーションはこの設定を継承するため、ルートサイトの web.config に設定する必要があります。

  4. Cloudflare には、互いに独立したボットブロックシステムが複数あります。

    • 「Block AI Bots」(WAF 管理ルール)— AI クローラーのアクセスを制御します。AI Crawl Control で Claude-User を許可してください。
    • 「Bot Fight Mode」 — ホスティングプロバイダーの IP からの自動トラフィックをブロックします。WAF ルールでは回避できません。回避するには IP Access Rules を使用するしかありません。
  5. Cloudflare 経由のサーバー間通信には、ホワイトリスト登録が必要です。 サーバーが自分自身のパブリックドメインに HTTP リクエストを送信すると、そのリクエストは Cloudflare を経由し、ボットトラフィックとして検出されます。送信側の HttpClient には必ず User-Agent ヘッダーを設定し、Cloudflare IP Access Rules でサーバーの送信元 IP をホワイトリストに登録してください。

  6. Azure App Service から localhost への接続はできません。 サンドボックスにより、127.0.0.1:80 への送信ソケット接続が禁止されています。同じ App Service 内のサーバー間通信には、パブリックホスト名を使用する必要があります。

  7. 発行元が異なる JWT トークンには、ValidIssuers/ValidAudiences 配列が必要です。 MCP サーバーが既存のユーザー認証システムとは異なる発行元/オーディエンス値でトークンを発行する場合、JWT Bearer ハンドラーで両方を受け入れる必要があります。単数形のプロパティではなく、複数形の配列プロパティを使用してください。

  8. Azure SQL Serverless のコールドスタートは、問題が連鎖する原因になることがあります。 一時停止中のデータベースの再開には、15~30 秒以上かかります。データベースが起動する前に MCP HttpClient のタイムアウト(30 秒)に達すると、ツール呼び出しは失敗します。サーバーレスデータベースでは、EnableRetryOnFailure と余裕のあるタイムアウトの設定を検討してください。

  9. Cloudflare API の認証: Global API Key では X-Auth-Email と X-Auth-Key ヘッダーを使います。Authorization: Bearer ではありません。API Token(スコープ付き)では Authorization: Bearer を使います。誤った形式を使うと Unable to authenticate request が返されます。

  10. JwtSecurityTokenHandler はクレームタイプを暗黙的に変更します。 OutboundClaimTypeMap は、JWT のシリアル化時に ClaimTypes.NameIdentifier を "sub" に、ClaimTypes.Name を "unique_name" に変換します。受信側では、MapInboundClaims(既定値は true)によってこの変換が元に戻る場合と戻らない場合があります。これはハンドラーの実装に依存します(.NET 8 の JsonWebTokenHandler では元に戻りません)。クレームタイプがエンドツーエンドで予測可能になるよう、トークンの作成前に必ずクレームを標準的な JWT の短縮名に明示的に正規化し、OutboundClaimTypeMap をクリアして、JWT ハンドラーで MapInboundClaims = false を設定してください。

  11. JWT Bearer スキームで検証を実行するには、[Authorize] が必要です。 すべてのリクエストでグローバルに実行され、セッション Cookie から User.Claims を設定する Cookie/Identity ミドルウェアとは異なり、JWT Bearer ハンドラーは、エンドポイントに [Authorize](またはそのスキームを参照するポリシー)が指定されている場合にのみトークンを検証します。指定がない場合、Authorization ヘッダー内の Bearer トークンは無視され、リクエストは匿名として処理され、User.Claims は空になります。コントローラーに公開エンドポイントと保護されたエンドポイントが混在する場合は、クラスレベルで [Authorize(Policy = "...")] を使用し、公開エンドポイントには [AllowAnonymous] を指定してください。

  12. JSON のプロパティ名は、API のシリアル化時の大文字と小文字の形式に一致させる必要があります。 MedRecPro API は、PascalCase(camelCase への変換なし)で Newtonsoft.Json を使用しています。MCP プロジェクトで System.Text.Json を使って API の応答を解析する場合、TryGetProperty() では大文字と小文字が区別されます。"encryptedId" は "EncryptedUserId" に一致しません。API が返す正確なプロパティ名を必ず確認してください。

  13. 認可ロジックにおけるド・モルガンの法則。 if (!isSelf || !isAdmin) は if (!(isSelf && isAdmin)) と等価です。これは、どちらか一方ではなく、両方の条件が真であることを要求します。「自分自身または管理者なら許可」するには、if (!isSelf && !isAdmin) を使用してください。

トラブルシューティング

502 Bad Gateway

MCP アプリが起動時にクラッシュしています。次を確認してください。

  1. Kudu コンソール — https://<app>.scm.azurewebsites.net にアクセスし、LogFiles/ に移動して stdout-mcp* ログファイルを探します
  2. stdout ログを有効にする — site\wwwroot\mcp\web.config で stdoutLogEnabled="true" に設定し、URL に再度アクセスしてログを確認します
  3. よくある原因: Key Vault にアクセスできないことです。appsettings.Production.json で KeyVaultUrl が設定されていることと、マネージド ID にアクセス権があることを確認してください
IDX10703: key length is zero

JWT 署名キーが空です。これは、Key Vault のシークレットが読み込まれていないことを意味します。

  1. appsettings.Production.json で KeyVaultUrl が https://medrecprovault.vault.azure.net/ に設定されていることを確認します
  2. App Service のマネージド ID に、Key Vault のシークレットに対する Get および List のアクセス許可があることを確認します
  3. App Service の環境変数で、ASPNETCORE_ENVIRONMENT が Production に設定されていることを確認します
IDX10214 / IDX10205: Audience または Issuer の検証に失敗

McpTokenService が発行する JWT トークンでは、ServerUrl が発行者と対象者の両方として使用されます。JWT Bearer ハンドラーは、MCP の値と既存のユーザー認証値の両方を受け入れる必要があります。

ValidIssuers = new[] { jwtSettings.Issuer, mcpSettings.ServerUrl.TrimEnd('/') }
ValidAudiences = new[] { jwtSettings.Audience, mcpSettings.ServerUrl.TrimEnd('/') }
/mcp で 405 Method Not Allowed

これは想定どおりの動作です。/mcp の MCP Streamable HTTP トランスポートは POST リクエストのみを受け付けます。ブラウザーは GET を送信するため、405 が返されます。

下流 API の呼び出しで 403 Forbidden

MCP サーバーから https://www.medrecpro.com/api/... への送信 HTTP 呼び出しが、Cloudflare によってブロックされています。

  1. Cloudflare Firewall Events を確認する — ソースが botFight または managedChallenge のブロックを探します
  2. IP アクセスルールを確認する — Azure App Service のすべての送信 IP を Cloudflare で許可リストに登録する必要があります(Security > WAF > Tools > IP Access Rules、アクション:Allow)
  3. User-Agent ヘッダーを確認する — HttpClient は空でない User-Agent を送信する必要があります。Program.cs で client.DefaultRequestHeaders.Add("User-Agent", ...) を確認してください
  4. 送信 IP を取得する: az webapp show --resource-group <rg> --name <app> --query possibleOutboundIpAddresses --output tsv
OAuth コールバックエラー
  1. Google Cloud Console と Microsoft Entra ID にリダイレクト URI が登録されていることを確認します
  2. McpServer:ServerUrl に /mcp が含まれていることを確認します(例:https://www.medrecpro.com/mcp)
  3. コールバック URL は {ServerUrl}/oauth/callback/{provider} として構築されます
SSE 接続の切断
  1. Cloudflare の変換ルールで、/mcp パスに対して X-Accel-Buffering: no が設定されていることを確認します
  2. Cloudflare のキャッシュルールで、/mcp パスがキャッシュをバイパスすることを確認します
  3. Azure App Service の常時接続が有効になっていることを確認します
最初のツール呼び出しでデータベースがタイムアウトする

Azure SQL Serverless が一時停止している可能性があります。最初のリクエストで再開が開始され、15~30 秒以上かかることがあります。

  1. 再試行 — データベースの起動後、2 回目の試行で通常は成功します
  2. 自動一時停止までの時間を延長 — テスト中は Azure Portal でサーバーレスの自動一時停止までの時間を 10~15 分に設定します
  3. 再試行ロジックを追加 — UseSqlServer() の設定で EnableRetryOnFailure() を検討します

MCP レジストリへの公開

このサーバーは、MCP クライアントが発見できるよう、公式の MCP Registry に登録されています。

レジストリエントリ: com.medrecpro/drug-label-server レジストリ検索: https://registry.modelcontextprotocol.io/v0.1/servers?search=medrecpro

前提条件
  1. mcp-publisher CLI — GitHub リリースからインストールします:

    # Windows (PowerShell)
    $arch = if ([System.Runtime.InteropServices.RuntimeInformation]::ProcessArchitecture -eq "Arm64") { "arm64" } else { "amd64" }
    Invoke-WebRequest -Uri "https://github.com/modelcontextprotocol/registry/releases/latest/download/mcp-publisher_windows_$arch.tar.gz" -OutFile "mcp-publisher.tar.gz"
    tar xf mcp-publisher.tar.gz mcp-publisher.exe
    rm mcp-publisher.tar.gz
    
  2. Ed25519 キーペア — DNS ドメインの検証に使用します(ローカルに保存し、リポジトリには保存しません)

  3. DNS TXT レコード — Cloudflare ですでに設定されています:

    medrecpro.com TXT "v=MCPv1; k=ed25519; p=<public-key>"
    
server.json

レジストリのメタデータファイルは MedRecProMCP/server.json にあります:

{
  "$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
  "name": "com.medrecpro/drug-label-server",
  "title": "MedRecPro Drug Label Server",
  "description": "Search and export FDA drug labels by brand name, generic ingredient, or UNII code.",
  "version": "1.0.0",
  "websiteUrl": "https://www.medrecpro.com",
  "icons": [
    {
      "src": "https://www.medrecpro.com/favicon.svg",
      "mimeType": "image/svg+xml",
      "sizes": ["any"]
    },
    {
      "src": "https://www.medrecpro.com/favicon-96x96.png",
      "mimeType": "image/png",
      "sizes": ["96x96"]
    }
  ],
  "repository": {
    "url": "https://github.com/chriserikbarnes/MedRecPro",
    "source": "github",
    "subfolder": "MedRecProMCP"
  },
  "remotes": [
    {
      "type": "streamable-http",
      "url": "https://www.medrecpro.com/mcp"
    }
  ]
}

主なポイント:

  • name には com.medrecpro/ 名前空間を使用します(DNS による検証済み)
  • icons には、クライアントでの表示用に SVG(スケーラブル)と 96x96 PNG を指定します
  • remotes は、これがホスト型サーバーであることを宣言します(npm/PyPI パッケージではありません)
  • packages は、このサーバーがパッケージとして配布されないため省略します
公開手順
  1. DNS 検証で認証します:

    mcp-publisher.exe login dns --domain=medrecpro.com --private-key=<64-char-hex-private-key>
    

    ⚠️ 秘密鍵は、リポジトリ外にあるローカルスクリプトに保存されています。C:\Users\{user}\{folder}\{publisher-script}.ps1 を参照してください

  2. レジストリに公開します:

    mcp-publisher.exe publish server.json
    
  3. 掲載を確認します:

    curl "https://registry.modelcontextprotocol.io/v0.1/servers?search=medrecpro"
    
更新を公開するタイミング

ツールの追加、削除、名前変更、サーバー URL の変更、または説明やメタデータの更新を行う場合は、server.json の version を上げて再公開します。

  • ツールの追加、削除、名前変更
  • サーバー URL の変更
  • 説明またはメタデータの更新

レジストリには各バージョンが個別に保存されます。公開してもコードはデプロイされません。カタログエントリが更新されるだけです。

後方互換性の維持

デプロイ済みのサーバーは単一インスタンスであり、バージョン管理されたパッケージではないため、破壊的変更は避けてください。

✅ 安全な変更❌ 破壊的変更
新しいツールの追加既存ツールの削除
オプションパラメーターの追加パラメーターの削除または名前変更
新しいレスポンスフィールドの追加レスポンス構造の変更
バグ修正/ロジックの改善ツール名の変更
説明の改善必須フィールドの削除
DNS 検証リファレンス

キーペアを再生成する場合や、新しいマシンで設定する場合:

# Generate Ed25519 keypair (use Git Bash on Windows)
openssl genpkey -algorithm Ed25519 -out mcp-key.pem

# Extract public key (Base64) — goes in DNS TXT record
openssl pkey -in mcp-key.pem -pubout -outform DER | tail -c 32 | base64

# Extract private key (64-char hex) — used with CLI
openssl pkey -in mcp-key.pem -noout -text 2>&1 | grep -A3 "priv:" | tail -n +2 | tr -d ' :\n'

DNS TXT レコードの形式(Cloudflare):

  • タイプ: TXT
  • 名前: @(ルートドメイン)
  • 内容: v=MCPv1; k=ed25519; p=<base64-public-key>

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。