MedRecPro Drug Label Server

平台与服务

by chriserikbarnes

支持按 brand name、generic ingredient 或 UNII code 搜索并导出 FDA 药品标签数据。

什么是 MedRecPro Drug Label Server

支持按 brand name、generic ingredient 或 UNII code 搜索并导出 FDA 药品标签数据。

README

MedRecPro

MedRecPro is a pharmaceutical structured product label (SPL) management platform built with ASP.NET Core. It provides secure access to FDA drug label data through a RESTful API, an AI-powered chat interface, and a Model Context Protocol (MCP) server for integration with AI assistants like Claude.

Specifications

Technology Stack

  • Runtime: ASP.NET Core (.NET 8.0 LTS)
  • Database: Azure SQL Server (Serverless free tier) with Dapper + Entity Framework Core
  • Authentication: Cookie-based auth with Google and Microsoft OAuth providers; JWT bearer tokens for API access; McpBearer JWT scheme for MCP server integration (claims normalized to standard JWT short names: sub, name, email)
  • AI Integration: Claude API for natural language query interpretation and synthesis
  • MCP Protocol: Model Context Protocol server with OAuth 2.1 (PKCE S256) for Claude.ai connector integration
  • Hosting: Azure App Service (Windows, IIS) with Cloudflare CDN/WAF/DNS
  • Secrets: Azure Key Vault
  • API Documentation: Swagger/OpenAPI
  • SPL Rendering: RazorLight templates for SPL XML-to-HTML generation

Solution Architecture

The solution consists of five projects deployed to a single Azure App Service using IIS virtual applications:

code
                        Cloudflare (CDN/WAF/DNS)
                                |
                                v
    Azure App Service: "MedRecPro" (Windows, IIS)
   +--------------------------------------------------------+
   |                                                        |
   |  /          site\wwwroot       MedRecProStatic         |
   |  /api       site\wwwroot\api   MedRecPro API           |
   |  /mcp       site\wwwroot\mcp   MedRecProMCP            |
   |                                                        |
   +--------------------------------------------------------+
                        |
                        v
               Azure Key Vault
              (medrecprovault)
Virtual PathProjectPurpose
/MedRecProStaticStatic site, marketing pages, AI chat UI, OAuth/MCP discovery metadata
/apiMedRecProREST API: SPL parsing, label CRUD, authentication, AI interpret/synthesize
/mcpMedRecProMCPMCP server: OAuth 2.1 gateway for Claude.ai integration
(CLI)MedRecProConsoleStandalone bulk import utility (SPL labels and FDA Orange Book)
(library)MedRecProImportClassShared class library: entity models, parsing services, and EF Core context for SPL and Orange Book import
(test)MedRecProTestUnit and integration tests

How the Projects Relate

MedRecProStatic is the user-facing front end. Its AI chat interface (/Home/Chat) communicates with the API using a request-interpret-execute-synthesize pattern: user queries are sent to the API's AI endpoints, which use Claude to map natural language to API calls. The static site also serves OAuth/MCP discovery metadata (/.well-known/*) at the domain root on behalf of the MCP server, because the MCP SDK resolves discovery URLs relative to the domain root rather than the /mcp path.

MedRecPro (API) is the core backend. It handles SPL XML parsing and import, label data CRUD, user authentication, AI query interpretation via Claude, database views for navigation, and SPL document rendering via RazorLight templates.

MedRecProMCP is an OAuth 2.1 gateway that exposes MedRecPro API capabilities as MCP tools. When Claude.ai connects, it authenticates users through Google/Microsoft OAuth, resolves upstream identity provider identities to numeric database user IDs (auto-provisioning new users if needed), then forwards authenticated MCP JWTs to the MedRecPro API. It uses JWT tokens, PKCE (S256), Dynamic Client Registration (RFC 7591), and a shared PKSecret for encrypted user ID exchange with the API.

Repository File Structure

code
MedRecPro/                          # Root repository
  README.md                         # This file
  .gitignore
  LICENSE.txt

  MedRecPro/                        # ASP.NET Core Web API
    Program.cs                      # App startup, DI, middleware
    MedRecPro.csproj                # .NET 8.0 project file
    appsettings.json                # Base configuration
    appsettings.Development.json    # Local dev overrides
    web.Release.config              # IIS release config
    Controllers/
      ApiControllerBase.cs          # Base controller (route prefix, #if DEBUG directives)
      AuthController.cs             # OAuth login/logout, user info
      UsersController.cs            # User CRUD, activity logs, authentication, MCP user resolution/provisioning
                                      #   [Authorize(Policy = "ApiAccess")] — accepts both cookie auth and McpBearer JWT
                                      #   signup and authenticate endpoints use [AllowAnonymous]
      LabelController.cs            # Label CRUD, views, search, import, AI endpoints
      AiController.cs               # AI interpret/synthesize, conversations, context
      SettingsController.cs         # App info, feature flags, metrics, logs, cache
    Service/
      SplImportService.cs           # SPL ZIP file import and parsing orchestration
      SplParsingService.cs          # Core SPL XML parsing
      SplDataService.cs             # Database operations for label data
      SplContextService.cs          # SPL document context management
      SplDocumentRenderingService.cs    # SPL-to-HTML rendering via RazorLight
      SplStructuredBodyRenderingService.cs
      SplSectionRenderingService.cs
      SplIngredientRenderingService.cs
      SplPackageRenderingService.cs
      SplCharacteristicRenderingService.cs
      SplAuthorRenderingService.cs
      SplTextContentRenderingService.cs
      SplRenderingRegistrationService.cs
      TarpitService.cs              # IP tracking, delay calculation, endpoint abuse detection
      ViewRenderService.cs          # Razor view rendering
      ZipImportWorkerService.cs     # Background ZIP import worker
      BackgroudTaskService.cs       # Background task management
      DatabaseKeepAliveService.cs   # Keeps Azure SQL Serverless awake during business hours
      AzureTokenCredentialService.cs
      AzureAppHostTokenCredentialService.cs
      ParsingServices/              # 20+ specialized SPL XML parsers
        SectionParser.cs
        ProductIdentityParser.cs
        PackagingParser.cs
        ... (and more)
      ParsingValidators/            # SPL validation services
    DataAccess/
      RepositoryDataAccess.cs       # Core data access layer
      UserDataAccess.cs             # User-specific queries
      DtoLabelAccess.cs             # Label DTO queries (base)
      DtoLabelAccess-Views.cs       # Database view queries
      DtoLabelAccess-Document.cs    # Document queries
      DtoLabelAccess-Ingredient.cs  # Ingredient queries
      DtoLabelAccess-Organization.cs
      DtoLabelAccess-ProductHierarchy.cs
      DtoLabelAccess-ContentHierarchy.cs
      DtoLabelAccess-BatchLoaders.cs
      ... (and more)
    Middleware/
      TarpitMiddleware.cs           # Progressive delay for 404 abuse and endpoint rate limiting
    Models/                         # Domain models, DTOs, enums
      Labels.cs                     # Core label entities
      User.cs                       # User model
      Import.cs                     # Import models
      Comparison.cs                 # Label comparison models
      SectionStructure.cs           # Section hierarchy
      DocumentRendering.cs          # Rendering models
      TarpitSettings.cs             # Tarpit configuration (thresholds, delays, monitored endpoints)
      ... (and more)
    Skills/                         # AI skill definitions (markdown prompts for Claude)
      skills.md                     # Master skill index
      selectors.md                  # Query routing rules
      retryPrompt.md                # Retry logic prompt
      labelProductIndication.md     # Indication discovery skill
      equianalgesicConversion.md    # Opioid conversion skill
      product-extraction.md         # Product extraction skill
      pharmacologic-class-matching.md
      interfaces/                   # Modular skill interface definitions
        response-format.md
        synthesis-rules.md
        api/                        # API-specific skill docs
          indication-discovery.md
          label-content.md
          equianalgesic-conversion.md
          pharmacologic-class.md
          product-extraction-api.md
          user-activity.md
          cache-management.md
          session-management.md
          data-rescue.md
          retry-fallback.md
      prompts/                      # AI prompt templates
        product-extraction-prompt.md
        pharmacologic-class-matching-prompt.md
    Views/
      SplTemplates/                 # RazorLight templates for SPL XML rendering
        GenerateSpl.cshtml          # Main SPL generation template
        _Section.cshtml             # Section partial
        _Product.cshtml             # Product partial
        _Ingredient.cshtml          # Ingredient partial
        _Packaging.cshtml           # Packaging partial
        _Author.cshtml              # Author partial
        ... (18 templates total)
      Stylesheets/                  # SPL rendering stylesheets
    Helpers/                        # Utility classes
      ClaimHelper.cs                # Centralized claim extraction (cookie auth + MCP JWT)
      EncryptionHelper.cs           # ID encryption/decryption
      ConnectionStringHelper.cs     # DB connection management
      XmlHelpers.cs                 # XML parsing utilities
      ... (and more)
    Auth/
      BasicAuthenticationHandler.cs # Basic auth handler
    Attributes/                     # Custom validation attributes for SPL fields
    Filters/
      ActivityLogActionFilter.cs    # Request activity logging
      RequireActorAttributeFilter.cs      # Actor-based authorization filter
      RequireUserRoleAttributeFilter.cs   # Role-based authorization filter
    Migrations/                     # EF Core migrations
    Exceptions/
    SQL/                            # Database schema and maintenance scripts
      MedRecPro.sql                 # Full database schema
      MedRecPro_Views.sql           # View definitions
      MedRecPro_Indexes.sql         # Index definitions
      MedRecPro-Deployment.sql      # Deployment scripts
      DbTriggerSetup.sql            # Database triggers
      MedRecPro-Export-Import.ps1   # PowerShell export/import script
      MedRecPro-AzureStatus.sql     # Azure status queries
      MedRecPro-AzureRebuildIndex.sql
      MedRecPro-AzureDisableIndex.sql
      MedRecPro-AzureNuke.sql       # Full database reset (use with caution)
      MedRecPro-AzureOnlineQueryEditorRebuildIndex.sql
      MedRecPro-TableNames.sql
      MedRecPro-TableTruncate.sql
      MedRecPro-TableMissingIndexes.sql
      MedRecPro-TableCreate-OrangeBook.sql  # Orange Book table definitions (7 tables)
      MedRecPro-AzureOrangeBookNuke.sql     # Orange Book targeted truncation

  MedRecProStatic/                  # Static site and AI chat interface
    Program.cs                      # Startup, middleware, OAuth discovery endpoints
    MedRecProStatic.csproj          # .NET 8.0 project file
    web.config                      # IIS config (httpErrors PassThrough, handler isolation)
    appsettings.json
    appsettings.Development.json
    Controllers/
      HomeController.cs             # Index, Terms, Privacy, Chat pages
    Middleware/
      TarpitMiddleware.cs           # Progressive delay for 404 abuse and endpoint rate limiting
    Models/
      PageContent.cs                # Strongly-typed content models
      TarpitSettings.cs             # Tarpit configuration (thresholds, delays, monitored endpoints)
    Services/
      ContentService.cs             # JSON content loader
      TarpitService.cs              # IP tracking, delay calculation, endpoint abuse detection
    Views/
      Home/
        Index.cshtml                # Landing page
        Terms.cshtml                # Terms of Service
        Privacy.cshtml              # Privacy Policy
        Chat.cshtml                 # AI chat interface
      Shared/
        _Layout.cshtml              # Master layout
    Content/
      config.json                   # Site config (URLs, branding, version)
      pages.json                    # Page content (home, terms, privacy)
    wwwroot/
      css/                          # Stylesheets
      js/
        site.js                     # Global scripts
        chat/                       # AI chat modules (18 files)
          index.js                  # Main orchestrator
          api-service.js            # API communication
          endpoint-executor.js      # API endpoint execution
          batch-synthesizer.js      # Response synthesis
          checkpoint-manager.js     # State checkpoints
          checkpoint-renderer.js    # Progress UI rendering
          message-renderer.js       # Chat message rendering
          markdown.js               # Markdown-to-HTML
          config.js                 # Chat configuration
          state.js                  # Client state management
          ... (and more)
      lib/                          # Third-party (Bootstrap, jQuery)

  MedRecProMCP/                     # MCP Server (OAuth 2.1 gateway)
    Program.cs                      # Startup, DI, endpoint mappings
    MedRecProMCP.csproj             # .NET 8.0 project file
    server.json                     # MCP registry metadata
    web.config                      # IIS config
    appsettings.json / .Development.json / .Production.json
    Configuration/
      McpServerSettings.cs
      MedRecProApiSettings.cs
      JwtSettings.cs
      OAuthProviderSettings.cs
    Endpoints/
      OAuthEndpoints.cs             # OAuth authorize, token, register, callbacks
      OAuthMetadataEndpoints.cs     # .well-known metadata
    Services/
      McpTokenService.cs            # JWT token generation/validation
      OAuthService.cs               # OAuth flow orchestration
      ClientRegistrationService.cs  # Dynamic Client Registration (RFC 7591)
      PkceService.cs                # PKCE implementation
      FilePersistedCacheService.cs  # File-based persistent cache
      MedRecProApiClient.cs         # HTTP client for API calls
      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 (copy from API for user ID decryption)
    Tools/
      DrugLabelTools.cs             # MCP tools: drug label search and export
      UserTools.cs                  # MCP tools: user/account operations
    Models/
      AiAgentDtos.cs                # AI integration models
      WorkPlanModels.cs             # Work plan models
    Templates/
      McpDocumentation.html         # Embedded docs page

  MedRecProConsole/                 # Bulk import CLI tool (SPL + Orange Book)
    Program.cs                      # Entry point, interactive menu, CLI argument dispatch
    Services/
      ImportService.cs              # SPL import orchestration
      ImportProgressTracker.cs      # SPL progress tracking
      OrangeBookImportService.cs    # Orange Book import orchestration (ZIP extraction, truncation, progress)
    Models/
      AppSettings.cs
      CommandLineArgs.cs            # CLI args: --orange-book, --nuke, --connection, --auto-quit, --verbose
      ImportParameters.cs
      ImportQueueItem.cs
      ImportResults.cs
      ImportProgressFile.cs
    Helpers/
      ConfigurationHelper.cs
      ConsoleHelper.cs              # Interactive menu (import, orange-book/ob, database/db, help, quit)
      HelpDocumentation.cs

  MedRecProImportClass/             # Shared class library for import operations
    Models/
      OrangeBook.cs                 # Orange Book entity classes (Applicant, Product, Patent, Exclusivity, junctions)
      ... (SPL models)
    Service/
      ParsingServices/
        OrangeBookProductParsingService.cs  # Orange Book products.txt parsing, batch upserts, entity matching
        ... (20+ SPL parsers)
    Context/
      ApplicationDbContext.cs       # EF Core context (auto-registers OrangeBook entities via reflection)

  MedRecProTest/                    # Unit and integration tests
    SplImportServiceTests.cs
    ProductRenderingServiceTests.cs
    ComparisonServiceTests.cs
    UserDataAccessTests.cs
    LogActivityAsyncTests.cs
    StringCipherTests.cs
    ResolveMcpUserTests.cs          # MCP user resolution and auto-provisioning tests
    TarpitServiceTests.cs           # Tarpit service unit tests (404 tracking + endpoint abuse)
    TarpitMiddlewareTests.cs        # Tarpit middleware integration tests

API Endpoints Summary

All API endpoints are accessed under /api in production (IIS virtual application). Controllers use #if DEBUG directives to handle the path prefix difference between local development (/api/[controller]) and production where IIS strips the /api prefix.

Authentication (/api/Auth)

MethodRouteDescription
GETlogin/{provider}Start OAuth flow (Google or Microsoft)
GETexternal-logincallbackOAuth callback handler
GETuserGet current authenticated user info
POSTlogoutLog out current user
POSTtoken-placeholderToken exchange
GETloginLogin page
GETloginfailureLogin failure handler
GETlockoutAccount lockout handler
GETaccessdeniedAccess denied handler

Users (/api/Users)

MethodRouteDescription
GETmeGet current user profile
GET{encryptedUserId}Get user by encrypted ID
GETbyemailGet user by email
POSTsignupCreate new user account
POSTauthenticateAuthenticate user
PUT{encryptedUserId}/profileUpdate user profile
DELETE{encryptedUserId}Delete user account
PUTadmin-updateAdministrative user update
POSTrotate-passwordRotate user password
GETuser/{encryptedUserId}/activityGet user activity log
GETuser/{encryptedUserId}/activity/daterangeGet activity within date range
GETendpoint-statsGet endpoint performance statistics
POSTresolve-mcpResolve email to encrypted user ID (McpBearer auth; auto-provisions new users)

Labels (/api/Label)

The main data controller with 40+ endpoints covering navigation views, search, CRUD, import, rendering, and AI features.

Navigation & Search Views:

MethodRouteDescription
GETproduct/searchSearch products
GETproduct/relatedRelated products
GETproduct/latestLatest product labels
GETproduct/latest/detailsLatest product label details
GETproduct/indicationsProduct indications search
GETingredient/searchSearch by ingredient (active/inactive)
GETingredient/summariesIngredient summary list
GETingredient/active/summariesActive ingredients only
GETingredient/inactive/summariesInactive ingredients only
GETingredient/advancedAdvanced ingredient search
GETingredient/by-applicationIngredients by application number
GETingredient/relatedRelated ingredients
GETlabeler/searchSearch by manufacturer/labeler
GETlabeler/summariesLabeler summary list
GETndc/searchSearch by NDC code
GETndc/package/searchSearch by NDC package code
GETapplication-number/searchSearch by application number (NDA/ANDA)
GETapplication-number/summariesApplication number summaries
GETpharmacologic-class/searchSearch by pharmacologic class
GETpharmacologic-class/hierarchyPharmacologic class hierarchy
GETpharmacologic-class/summariesPharmacologic class summaries
GETsection/searchSearch by LOINC section code
GETsection/summariesSection summaries
GETdocument/navigationDocument navigation tree
GETdocument/version-history/{setGuidOrDocumentGuid}Document version history

Label Content & Rendering:

MethodRouteDescription
GETsection/content/{documentGuid}Get section content for a document
GETmarkdown/sections/{documentGuid}Get label sections as markdown
GETmarkdown/export/{documentGuid}Export full label as markdown
GETmarkdown/download/{documentGuid}Download label markdown file
GETmarkdown/display/{documentGuid}Render label as HTML from markdown
GETgenerate/{documentGuid}/{minify}Generate updated SPL XML
GEToriginal/{documentGuid}/{minify}Get original SPL XML
GETsingle/{documentGuid}Get single label details
GETcomplete/{pageNumber?}/{pageSize?}Paginated complete label list

Drug Safety:

MethodRouteDescription
GETdrug-safety/dea-scheduleDEA schedule classification

AI-Powered Endpoints:

MethodRouteDescription
GETextract-productAI-powered product extraction from text
GETcomparison/analysis/{documentGuid}Get comparison analysis
POSTcomparison/analysis/{documentGuid}Start AI comparison analysis
GETcomparison/progress/{operationId}Check comparison progress

CRUD & Import:

MethodRouteDescription
GET{menuSelection}/{encryptedId}Get single entity by type
POST{menuSelection}Create entity by type
PUT{menuSelection}/{encryptedId}Update entity by type
DELETE{menuSelection}/{encryptedId}Delete entity by type
POSTimportBulk SPL ZIP import
GETimport/progress/{operationId}Check import progress

Reference:

MethodRouteDescription
GETguideAPI usage guide
GETinventory/summaryDatabase inventory overview
GETsectionMenuAvailable section menu items
GET{menuSelection}/documentationDocumentation for a data type

AI (/api/Ai)

MethodRouteDescription
GETcontextGet AI context (auth status, demo mode, data counts)
POSTinterpretInterpret natural language query into API endpoint specs
POSTsynthesizeSynthesize API results into human-readable response
GETchatConvenience endpoint for simple queries
POSTconversationsCreate new conversation
GETconversations/{conversationId}Get conversation
GETconversations/{conversationId}/historyGet conversation history
DELETEconversations/{conversationId}Delete conversation
GETconversations/statsGet conversation statistics
POSTretryRetry last AI operation

Settings (/api/Settings)

MethodRouteDescription
GETdemomodeCheck demo mode status
GETinfoApplication info
GETfeaturesFeature flags
GETdatabase-limitsDatabase limits
GETmetrics/database-costAzure SQL free tier usage and cost projections
POSTclearmanagedcacheClear managed cache
GETlogsActivity logs
GETlogs/statisticsLog statistics
GETlogs/categoriesLog categories
GETlogs/by-dateLogs filtered by date
GETlogs/by-categoryLogs filtered by category
GETlogs/by-userLogs filtered by user
GETlogs/usersUsers with log entries
GETtest/app-credentialTest Azure credentials
GETtest/app-metrics-pipelineTest metrics pipeline

MCP Server (/mcp)

The MCP server exposes its own endpoints. See the MedRecProMCP README for full details.

MethodRouteDescription
POST/mcpMCP Streamable HTTP transport (JSON-RPC)
GET/mcp/healthHealth check
GET/mcp/docsHTML documentation page
GET/mcp/.well-known/oauth-protected-resourceProtected Resource Metadata (RFC 9728)
GET/mcp/.well-known/oauth-authorization-serverAuthorization Server Metadata (RFC 8414)
GET/mcp/oauth/authorizeOAuth authorization endpoint
POST/mcp/oauth/tokenToken exchange endpoint
POST/mcp/oauth/registerDynamic Client Registration (RFC 7591)
GET/mcp/oauth/callback/googleGoogle OAuth callback
GET/mcp/oauth/callback/microsoftMicrosoft OAuth callback

MedRecProStatic and MCP Relationship

MedRecProStatic serves the OAuth/MCP discovery metadata at the domain root because the MCP SDK resolves /.well-known/* relative to the domain, not the MCP endpoint path. When Claude connects to https://www.medrecpro.com/mcp, the SDK looks for discovery at https://www.medrecpro.com/.well-known/oauth-protected-resource and /.well-known/oauth-authorization-server.

These endpoints are registered directly in MedRecProStatic's Program.cs as static JSON responses. Attempts to redirect from the root site to /mcp/.well-known/* failed because 302 redirects cause the MCP SDK to derive the wrong resource URI, and reverse proxying through Cloudflare triggers Bot Fight Mode (403 errors).

MedRecProStatic also has a critical web.config setting (httpErrors existingResponse="PassThrough") placed outside the <location> element so it is inherited by the MCP and API virtual applications. Without this, IIS replaces 401 responses with HTML error pages, breaking the MCP OAuth challenge flow.

Database Schema and SQL Scripts

Database schema definitions and maintenance scripts are maintained in MedRecPro/SQL/. These are the authoritative source for schema updates, view definitions, and index management.

ScriptPurpose
MedRecPro.sqlFull database schema (tables, constraints, relationships)
MedRecPro_Views.sqlView definitions used by navigation and search endpoints
MedRecPro_Indexes.sqlIndex definitions for query performance
MedRecPro-Deployment.sqlDeployment-time schema updates
DbTriggerSetup.sqlDatabase trigger configuration
MedRecPro-Export-Import.ps1PowerShell script for database export/import
MedRecPro-AzureStatus.sqlAzure SQL status and diagnostics queries
MedRecPro-AzureRebuildIndex.sqlIndex rebuild for Azure SQL
MedRecPro-AzureDisableIndex.sqlDisable indexes during bulk operations
MedRecPro-AzureOnlineQueryEditorRebuildIndex.sqlIndex rebuild via Azure Query Editor
MedRecPro-AzureNuke.sqlFull database reset (destructive)
MedRecPro-TableNames.sqlList all table names
MedRecPro-TableTruncate.sqlTruncate tables for reimport
MedRecPro-TableMissingIndexes.sqlIdentify missing indexes
MedRecPro-TableCreate-OrangeBook.sqlOrange Book table definitions (7 tables, indexes, extended properties)
MedRecPro-AzureOrangeBookNuke.sqlTargeted Orange Book truncation with safety preview mode

When updating database schemas or views, modify the scripts in MedRecPro/SQL/ and run them against the target database. The MedRecPro_Views.sql file is particularly important as the navigation view queries (ingredient search, labeler search, pharmacologic class hierarchy, etc.) are defined there and power many of the API search endpoints.

AI Skills System

The API includes an agentic AI layer that enables natural language interaction with pharmaceutical data. The system follows a request-interpret-execute-synthesize pattern:

  1. User submits a natural language query to POST /api/Ai/interpret
  2. Claude interprets the query and returns API endpoint specifications
  3. The client executes the specified API endpoints
  4. Results are sent to POST /api/Ai/synthesize
  5. Claude produces a human-readable response with suggested follow-ups

AI skills are defined as markdown prompt files in MedRecPro/Skills/. Key skills include:

  • Indication Discovery - Find drugs by indication/use case
  • Equianalgesic Conversion - Opioid dose conversion calculations
  • Product Extraction - AI-powered extraction of product details from text
  • Pharmacologic Class Matching - Map drugs to pharmacologic classifications
  • Label Content - Retrieve and synthesize label sections
  • Data Rescue - Fallback strategies for missing or incomplete data

FDA Orange Book Integration

The platform imports and cross-references data from the FDA's Approved Drug Products with Therapeutic Equivalence Evaluations (Orange Book), linking FDA approval records to existing SPL label data.

Orange Book Database Schema

Seven normalized tables store Orange Book data, with three junction tables linking to existing SPL entities:

TablePurpose
OrangeBookApplicantPharmaceutical companies holding FDA approvals
OrangeBookProductDrug products (natural key: ApplType + ApplNo + ProductNo)
OrangeBookPatentPatent records per product with expiration dates
OrangeBookExclusivityMarketing exclusivity periods (NCE, ODE, RTO, etc.)
OrangeBookProductMarketingCategoryJunction: OB Product → SPL MarketingCategory (by application number)
OrangeBookProductIngredientSubstanceJunction: OB Product → SPL IngredientSubstance
OrangeBookApplicantOrganizationJunction: OB Applicant → SPL Organization

No foreign key constraints are enforced; relationships are managed by the import module. The main nuke script (MedRecPro-AzureNuke.sql) excludes Orange Book tables, which have their own dedicated truncation script.

Orange Book Import Process

The console application (MedRecProConsole) imports Orange Book data from FDA-published ZIP archives containing tilde-delimited text files. The import pipeline:

  1. Extract products.txt from the ZIP archive
  2. Parse tilde-delimited rows (14 columns) into normalized entities
  3. Upsert applicants and products in batches (5,000 rows per batch)
  4. Match applicants to SPL organizations using a two-tier strategy:
    • Tier 1 (Normalized Exact): Strips corporate suffixes (INC, LLC, CORP, LTD, GMBH, etc.), punctuation, and whitespace; case-insensitive exact match
    • Tier 2 (Token Similarity): Two-pass fuzzy matching using Jaccard/containment scoring with a 0.67 threshold; strips pharma noise words on the second pass only when sufficient tokens remain
  5. Match ingredients to SPL IngredientSubstance records (semicolon-delimited ingredient lists parsed and matched individually)
  6. Match products to SPL MarketingCategory records via application number

The import is idempotent (upsert-based), so re-running is safe without crash recovery queues. Real-time multi-phase progress is displayed via Spectre.Console.

Orange Book CLI Usage

Interactive mode:

bash
cd MedRecProConsole
dotnet run
# Select "orange-book" or "ob" from the menu

Unattended mode:

bash
MedRecProConsole.exe --orange-book "path/to/EOBZIP_2026_01.zip" --nuke --auto-quit
ArgumentDescription
--orange-book <path>Path to Orange Book ZIP file
--nukeTruncate all Orange Book tables before import
--connection <name>Database connection name from appsettings.json
--auto-quitExit after completion
--verboseEnable debug logging

Getting Started

Prerequisites

  • .NET 8.0 SDK (LTS)
  • SQL Server (local) or Azure SQL Database
  • Visual Studio 2022 or VS Code

1. Clone the repository

bash
git clone <repo-url>
cd MedRecPro

2. Configure the API

Create user secrets for the MedRecPro API project:

bash
cd MedRecPro
dotnet user-secrets init
dotnet user-secrets set "Dev:DB:Connection" "Server=localhost;Database=MedRecProDB;User Id=sa;Password=your-password;"
dotnet user-secrets set "Security:DB:PKSecret" "your-encryption-key"
dotnet user-secrets set "Jwt:Key" "your-jwt-signing-key-min-32-chars"
dotnet user-secrets set "Jwt:Issuer" "MedRecPro"
dotnet user-secrets set "Jwt:Audience" "MedRecUsers"
dotnet user-secrets set "Authentication:Google:ClientId" "your-google-client-id"
dotnet user-secrets set "Authentication:Google:ClientSecret" "your-google-client-secret"
dotnet user-secrets set "Authentication:Microsoft:ClientId" "your-microsoft-app-id"
dotnet user-secrets set "Authentication:Microsoft:ClientSecret:Dev" "your-microsoft-secret"
dotnet user-secrets set "Authentication:Microsoft:TenantId" "your-tenant-id"
dotnet user-secrets set "ClaudeApiSettings:ApiKey" "your-claude-api-key"

3. Set up the database

Run the schema script from MedRecPro/SQL/MedRecPro.sql against your SQL Server instance, then apply views and indexes:

bash
# Apply schema, views, and indexes in order
sqlcmd -S localhost -d MedRecProDB -i MedRecPro/SQL/MedRecPro.sql
sqlcmd -S localhost -d MedRecProDB -i MedRecPro/SQL/MedRecPro_Views.sql
sqlcmd -S localhost -d MedRecProDB -i MedRecPro/SQL/MedRecPro_Indexes.sql

Or run EF Core migrations:

bash
cd MedRecPro
dotnet ef database update

4. Run the projects

bash
# Terminal 1: API (port 5093)
cd MedRecPro
dotnet run

# Terminal 2: Static site (port 5001)
cd MedRecProStatic
dotnet run

# Terminal 3: MCP server (port 5233, optional)
cd MedRecProMCP
dotnet run

5. Import data

Upload SPL ZIP files through the API import endpoint or use the console importer:

bash
cd MedRecProConsole
dotnet run -- --help

SPL ZIP files can be downloaded from the DailyMed SPL Resources page.

Orange Book ZIP files can be downloaded from the FDA Orange Book Data Files page. See the FDA Orange Book Integration section for import details.

Setup Pitfalls and Fixes

IIS Virtual Application Path Stripping

IIS strips the virtual application prefix from requests before forwarding to ASP.NET Core. A request to /api/Label/search arrives at Kestrel as /Label/search. All controllers use #if DEBUG compiler directives to handle this:

csharp
#if DEBUG
[Route("api/[controller]")]   // Local: full path
#else
[Route("[controller]")]        // Azure: IIS strips /api prefix
#endif

The same pattern applies to MCP routes and Swagger paths.

Cloudflare + Azure App Service Managed Certificates

Azure App Service Managed Certificates do not work with Cloudflare proxy enabled. Use Cloudflare Origin Certificates instead:

  1. Create an Origin Certificate in Cloudflare (SSL/TLS > Origin Server)
  2. Convert to PFX: openssl pkcs12 -export -out origin.pfx -inkey key.pem -in cert.pem
  3. Upload to Azure App Service > Certificates
  4. Bind to custom domains with SNI SSL

OAuth Redirect URI Prefix

Production redirect URIs must include the /api/ prefix:

  • Correct: https://your-domain.com/api/signin-google
  • Wrong: https://your-domain.com/signin-google

Cloudflare Bot Blocking

Cloudflare has multiple independent bot-blocking systems that can interfere with MCP and server-to-server calls:

  • "Block AI Bots" (WAF managed rule) - Must allow Claude-User via AI Crawl Control settings
  • "Bot Fight Mode" - Blocks requests from hosting provider IPs. Cannot be bypassed with WAF rules. Whitelist Azure App Service outbound IPs via IP Access Rules (Security > WAF > Tools)
  • Always set a User-Agent header on outbound HttpClients to avoid bot detection

Azure SQL Serverless Cold Starts

Azure SQL Serverless auto-pauses after inactivity. Resuming takes 30-60 seconds, which can exceed default timeouts. Mitigations:

  • DatabaseKeepAliveService pings the database with SELECT 1 every 14 minutes during business hours (Mon-Fri, 8 AM - 8 PM Eastern) to prevent auto-pause. Each ping cycle includes 3 retry attempts with escalating delays (10s, 30s, 60s) and a 90-second connect timeout to accommodate cold resume. Configured via the DatabaseKeepAlive section in appsettings.json
  • EnableRetryOnFailure() is configured on the EF Core DbContext with 3 retries and a 60-second command timeout to handle transient failures across all application database operations
  • Increase the auto-pause delay during active development

Key Vault Secret Naming

Key Vault uses -- (double dash) as separator; ASP.NET Core configuration uses : (colon). The framework maps between them automatically:

  • Key Vault: Authentication--Google--ClientId
  • Config: Authentication:Google:ClientId

Ensure no extra characters (trailing commas, quotes) in Key Vault secret values.

IIS httpErrors PassThrough

Without <httpErrors existingResponse="PassThrough" /> in the root site's web.config, IIS replaces HTTP 401 responses with HTML error pages. This breaks OAuth challenge flows where the WWW-Authenticate header must reach the client. This setting must be in the root site (MedRecProStatic) because child virtual applications inherit it.

JWT Multi-Issuer/Audience

When both the API and MCP server issue JWT tokens with different issuer/audience values, the JWT Bearer handler must accept both using ValidIssuers and ValidAudiences arrays instead of the singular properties.

Azure SQL Free Tier Monitoring

The API includes built-in monitoring for Azure SQL Database's serverless free tier (100,000 vCore seconds/month). The AzureSqlMetricsService queries Azure Monitor Metrics to track consumption, project monthly costs, and recommend throttling levels. See the GET /api/Settings/metrics/database-cost endpoint.

Security Configuration

Security settings should be stored in user secrets (development) or Azure Key Vault (production):

json
{
  "Authentication:Google:ClientId": "your-google-client-id.apps.googleusercontent.com",
  "Authentication:Google:ClientSecret": "your-google-client-secret",
  "Authentication:Microsoft:ClientId": "your-microsoft-app-id",
  "Authentication:Microsoft:ClientSecret:Dev": "your-microsoft-secret",
  "Authentication:Microsoft:ClientSecret:Prod": "your-microsoft-secret",
  "Authentication:Microsoft:TenantId": "your-tenant-id",
  "Security:DB:PKSecret": "your-encryption-key",
  "Jwt:Key": "your-jwt-signing-key",
  "Jwt:Issuer": "MedRecPro",
  "Jwt:Audience": "MedRecUsers",
  "Jwt:ExpirationMinutes": 60,
  "ClaudeApiSettings:ApiKey": "your-claude-api-key",
  "Dev:DB:Connection": "your-dev-connection-string",
  "Prod:DB:Connection": "your-prod-connection-string"
}

Changing Security:DB:PKSecret will break all existing encrypted URLs, favorites, and bookmarks.

Production Deployment

See the detailed deployment guides in each project's README:

  • MedRecProMCP README - MCP server setup, OAuth provider config, Cloudflare rules, Claude.ai connector integration, and troubleshooting
  • MedRecProStatic README - Static site deployment, content management, and IIS configuration

Deployment Checklist

  1. Publish each project to its virtual application path on Azure App Service
  2. Verify Azure Key Vault secrets are configured
  3. Purge Cloudflare cache after deployment
  4. Test authentication flows (Google and Microsoft OAuth)
  5. Verify Swagger UI loads at /api/swagger/index.html
  6. Verify MCP health check at /mcp/health
  7. Test AI chat at the static site

License

See the LICENSE.txt file for details.

常见问题

MedRecPro Drug Label Server 是什么?

支持按 brand name、generic ingredient 或 UNII code 搜索并导出 FDA 药品标签数据。

相关 Skills

MCP构建

by anthropics

Universal
热门

聚焦高质量 MCP Server 开发,覆盖协议研究、工具设计、错误处理与传输选型,适合用 FastMCP 或 MCP SDK 对接外部 API、封装服务能力。

想让 LLM 稳定调用外部 API,就用 MCP构建:从 Python 到 Node 都有成熟指引,帮你更快做出高质量 MCP 服务器。

平台与服务
未扫描114.1k

Slack动图

by anthropics

Universal
热门

面向Slack的动图制作Skill,内置emoji/消息GIF的尺寸、帧率和色彩约束、校验与优化流程,适合把创意或上传图片快速做成可直接发送的Slack动画。

帮你快速做出适配 Slack 的动图,内置约束规则和校验工具,少踩上传与播放坑,做表情包和演示都更省心。

平台与服务
未扫描114.1k

MCP服务构建器

by alirezarezvani

Universal
热门

从 OpenAPI 一键生成 Python/TypeScript MCP server 脚手架,并校验 tool schema、命名规范与版本兼容性,适合把现有 REST API 快速发布成可生产演进的 MCP 服务。

帮你快速搭建 MCP 服务与后端 API,脚手架完善、扩展顺手,尤其适合想高效验证服务能力的开发者。

平台与服务
未扫描10.2k

相关 MCP Server

Slack 消息

编辑精选

by Anthropic

热门

Slack 是让 AI 助手直接读写你的 Slack 频道和消息的 MCP 服务器。

这个服务器解决了团队协作中需要 AI 实时获取 Slack 信息的痛点,特别适合开发团队让 Claude 帮忙汇总频道讨论或发送通知。不过,它目前只是参考实现,文档有限,不建议在生产环境直接使用——更适合开发者学习 MCP 如何集成第三方服务。

平台与服务
83.4k

by netdata

热门

io.github.netdata/mcp-server 是让 AI 助手实时监控服务器指标和日志的 MCP 服务器。

这个工具解决了运维人员需要手动检查系统状态的痛点,最适合 DevOps 团队让 Claude 自动分析性能数据。不过,它依赖 NetData 的现有部署,如果你没用过这个监控平台,得先花时间配置。

平台与服务
78.4k

by d4vinci

热门

Scrapling MCP Server 是专为现代网页设计的智能爬虫工具,支持绕过 Cloudflare 等反爬机制。

这个工具解决了爬取动态网页和反爬网站时的头疼问题,特别适合需要批量采集电商价格或新闻数据的开发者。不过,它依赖外部浏览器引擎,资源消耗较大,不适合轻量级任务。

平台与服务
35.4k

评论