# ------------------------------------------------------------------------------------- # Server & Spring Boot # ------------------------------------------------------------------------------------- server: # Uncomment to serve FHIR under a non-default context path (e.g., /example/path/fhir) # servlet: # context-path: /example/path port: 8080 tomcat: # allow | as a separator in URLs relaxed-query-chars: "|" management: # Actuator endpoints: only /actuator/health exposed by default endpoints: enabled-by-default: false web: exposure: include: "health" # or "info,health,prometheus,metrics" or "*" for all endpoint: info: enabled: true metrics: enabled: true health: enabled: true probes: enabled: true group: liveness: include: [ "livenessState", "readinessState" ] prometheus: enabled: true prometheus: metrics: export: enabled: true spring: # ------------------------------------------------------------------------------- # A. Spring AI — Model Context Protocol (MCP) # ------------------------------------------------------------------------------- ai: # Run e.g. `npx @modelcontextprotocol/inspector` and connect to http://localhost:8080/mcp/messages using Streamable HTTP # Add the following to the MCP server settings file in e.g. cursor or claude (Desktop applications) for local debugging: # cursor: # { # "mcpServers": { # "hapi": { # "url": "http://localhost:8080/mcp/messages" # } # } # } # or claude: # { # "mcpServers": { # "hapi": { # "command": "npx", # "args": [ # "mcp-remote@latest", # "http://localhost:8080/mcp/messages" # ] # } # } # } mcp: server: name: FHIR MCP Server version: 1.0.0 instructions: "This server provides access to a FHIR RESTful API. You can use it to query FHIR resources, perform operations, and retrieve data in a structured format." enabled: true streamable-http: mcp-endpoint: /mcp/messages # ------------------------------------------------------------------------------- # B. Core Spring # ------------------------------------------------------------------------------- main: allow-bean-definition-overriding: false allow-circular-references: true autoconfigure: # This exclude is only needed for setups not using Elasticsearch where the elasticsearch sniff is not needed. exclude: org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientAutoConfiguration flyway: enabled: false baseline-on-migrate: true fail-on-missing-locations: false datasource: # url: "jdbc:h2:file:./target/database/h2" url: jdbc:h2:mem:test_mem username: sa password: null driver-class-name: org.h2.Driver # max-active: 15 # (ignored with HikariCP; use hikari.maximum-pool-size) hikari: maximum-pool-size: 10 jpa: properties: hibernate: format_sql: false show_sql: false # Hibernate dialect is auto-detected except for H2/Postgres. # If using H2: ca.uhn.fhir.jpa.model.dialect.HapiFhirH2Dialect # If using Postgres: ca.uhn.fhir.jpa.model.dialect.HapiFhirPostgresDialect dialect: ca.uhn.fhir.jpa.model.dialect.HapiFhirH2Dialect # --- Optional Hibernate DDL & tuning (commented out from source) --- hbm2ddl: auto: update jdbc: batch_size: 20 cache: use_query_cache: false use_second_level_cache: false use_structured_entries: false use_minimal_puts: false # --- Hibernate Search (Lucene/Elasticsearch) --- search: enabled: false # Lucene backend (default example) # backend: # type: lucene # analysis: # configurer: ca.uhn.fhir.jpa.search.HapiHSearchAnalysisConfigurers$HapiLuceneAnalysisConfigurer # directory: # type: local-filesystem # root: target/lucenefiles # lucene_version: lucene_current # Elasticsearch backend (alternative) — see also hapi.fhir.elasticsearch section in docs # backend: # type: elasticsearch # analysis: # configurer: ca.uhn.fhir.jpa.search.HapiHSearchAnalysisConfigurers$HapiElasticAnalysisConfigurer # ------------------------------------------------------------------------------------- # HAPI FHIR — grouped by domain # ------------------------------------------------------------------------------------- hapi: fhir: # ------------------------------------------------------------------------------- # A. Core Server & API # ------------------------------------------------------------------------------- openapi_enabled: true # Swagger UI at /fhir/swagger-ui/index.html; API docs at /fhir/api-docs fhir_version: R4 # DSTU2 | DSTU3 | R4 | R5 # use_apache_address_strategy: false # use_apache_address_strategy_https: false # custom_content_path: ./custom # folder name must be 'custom' # app_content_path: ./configs/app # served under /web/app # server_address: http://hapi.fhir.org/baseR4 # defer_indexing_for_codesystems_of_size: 101 # ------------------------------------------------------------------------------- # B. Implementation Guides (IG) & Package Install # ------------------------------------------------------------------------------- ig_runtime_upload_enabled: false # validate_resource_status_for_package_upload: false # default true # install_transitive_ig_dependencies: true # implementationguides: # swiss: # name: swiss.mednet.fhir # version: 0.8.0 # reloadExisting: false # installMode: STORE_AND_INSTALL # ips_1_0_0: # packageUrl: https://costateixeira.github.io/smart-ips-pilgrimage-fulltest/package.tgz # name: smart.who.int.ips-pilgrimage-test # version: 0.1.0 # installMode: STORE_AND_INSTALL # additionalResourceFolders: # - example # - example2 # supported_resource_types: # - Patient # - Observation # allowed_bundle_types: COLLECTION,DOCUMENT,MESSAGE,TRANSACTION,TRANSACTIONRESPONSE,BATCH,BATCHRESPONSE,HISTORY,SEARCHSET # ------------------------------------------------------------------------------- # C. Clinical Reasoning / CQL / Care Gaps / CDS Hooks # ------------------------------------------------------------------------------- cr: enabled: false # exposes Clinical Reasoning operation endpoints caregaps: reporter: "default" section_author: "default" terminologyServerClientSettings: maxRetryCount: 3 retryIntervalMillis: 1000 timeoutSeconds: 30 socketTimeout: 60 cql: use_embedded_libraries: true compiler: # low-level compiler options (typically not needed) # validate_units: true # verify_only: false # compatibility_level: "1.5" error_level: Info signature_level: All # analyze_data_requirements: false # collapse_data_requirements: false # translator_format: JSON # enable_date_range_optimization: true enable_annotations: true enable_locators: true enable_results_type: true enable_detailed_errors: true # disable_list_traversal: false # disable_list_demotion: false # enable_interval_demotion: false # enable_interval_promotion: false # disable_method_invocation: false # require_from_keyword: false # disable_default_model_info_load: false runtime: debug_logging_enabled: false # enable_validation: false # enable_expression_caching: true terminology: valueset_preexpansion_mode: REQUIRE # USE_IF_PRESENT | REQUIRE | IGNORE valueset_expansion_mode: PERFORM_NAIVE_EXPANSION # AUTO | USE_EXPANSION_OPERATION | PERFORM_NAIVE_EXPANSION valueset_membership_mode: USE_EXPANSION # AUTO | USE_VALIDATE_CODE_OPERATION | USE_EXPANSION code_lookup_mode: USE_VALIDATE_CODE_OPERATION # AUTO | USE_VALIDATE_CODE_OPERATION | USE_CODESYSTEM_URL data: search_parameter_mode: USE_SEARCH_PARAMETERS # AUTO | USE_SEARCH_PARAMETERS | FILTER_IN_MEMORY terminology_parameter_mode: FILTER_IN_MEMORY # AUTO | USE_VALUE_SET_URL | USE_INLINE_CODES | FILTER_IN_MEMORY profile_mode: DECLARED # ENFORCED | DECLARED | OPTIONAL | TRUST | OFF cdshooks: enabled: false clientIdHeaderName: client_id # ------------------------------------------------------------------------------- # D. Search & Indexing # ------------------------------------------------------------------------------- # NOTE: Extended Lucene/Elasticsearch indexing is experimental. # See https://hapifhir.io/hapi-fhir/docs/server_jpa/elastic.html advanced_lucene_indexing: false search_index_full_text_enabled: false # language_search_parameter_enabled: true # upliftedRefchains_enabled: true # index_storage_optimized: false # enable_index_missing_fields: false # enable_index_of_type: true # enable_index_contained_resource: false # store_resource_in_lucene_index_enabled: true # ------------------------------------------------------------------------------- # E. Bulk Operations # ------------------------------------------------------------------------------- bulk_export_enabled: false bulk_import_enabled: false # ------------------------------------------------------------------------------- # F. Write / Delete / Integrity # ------------------------------------------------------------------------------- # allow_cascading_deletes: true # allow_contains_searches: true # allow_external_references: true # allow_multiple_delete: true # allow_override_default_search_params: true # auto_create_placeholder_reference_targets: false # mass_ingestion_mode_enabled: false # auto_version_reference_at_paths: Device.patient, Device.location, Device.parent, DeviceMetric.parent, DeviceMetric.source, Observation.device, Observation.subject # client_id_strategy: ALPHANUMERIC # server_id_strategy: SEQUENTIAL_NUMERIC # enforce_referential_integrity_on_delete: false # enforce_referential_integrity_on_write: false # etag_support_enabled: true # expunge_enabled: true # fhirpath_interceptor_enabled: false # filter_search_enabled: true # graphql_enabled: true # Thread pool configuration for maintenance operations # Defaults to Runtime.getRuntime().availableProcessors() if not specified # reindex_thread_count: 4 # Number of threads to use for reindex operations # expunge_thread_count: 4 # Number of threads to use for expunge operations # mark_resources_for_reindexing_upon_search_parameter_change: false # ------------------------------------------------------------------------------- # G. Narrative & Validation # ------------------------------------------------------------------------------- narrative_enabled: false # validation: # requests_enabled: true # responses_enabled: true # ------------------------------------------------------------------------------- # H. MDM (Master Data Management) # ------------------------------------------------------------------------------- mdm_enabled: false mdm_rules_json_location: "mdm-rules.json" # userRequestRetryVersionConflictsInterceptorEnabled: false # ------------------------------------------------------------------------------- # I. Terminology / ValueSet Expansion # ------------------------------------------------------------------------------- # pre_expand_value_sets: true # enable_task_pre_expand_value_sets: true # pre_expand_value_sets_default_count: 1000 # pre_expand_value_sets_max_count: 1000 # maximum_expansion_size: 1000 logical_urls: - http://terminology.hl7.org/* - https://terminology.hl7.org/* - http://snomed.info/* - https://snomed.info/* - http://unitsofmeasure.org/* - https://unitsofmeasure.org/* - http://loinc.org/* - https://loinc.org/* # ------------------------------------------------------------------------------- # J. Partitioning & Multitenancy # ------------------------------------------------------------------------------- # partitioning: # allow_references_across_partitions: false # partitioning_include_in_search_hashes: false # default_partition_id: 0 # database_partition_mode_enabled: true # patient_id_partitioning_mode: true # request_tenant_partitioning_mode: false # ------------------------------------------------------------------------------- # K. CORS # ------------------------------------------------------------------------------- cors: allow_Credentials: true allowed_origin: - "*" # ------------------------------------------------------------------------------- # L. Search Orchestration # ------------------------------------------------------------------------------- search-coord-core-pool-size: 20 search-coord-max-pool-size: 100 search-coord-queue-capacity: 200 # Search Prefetch Thresholds. # This setting sets the number of search results to prefetch. For example, if this list # is set to [100, 1000, -1] then the server will initially load 100 results and not # attempt to load more. If the user requests subsequent page(s) of results and goes # past 100 results, the system will load the next 900 (up to the following threshold of 1000). # The system will progressively work through these thresholds. # A threshold of -1 means to load all results. Note that if the final threshold is a # number other than -1, the system will never prefetch more than the given number. # CSV list; -1 as final value means "all" search_prefetch_thresholds: 13,503,2003,-1 # ------------------------------------------------------------------------------- # M. Extensibility (custom beans / interceptors / providers) # ------------------------------------------------------------------------------- # comma-separated package names, will be @ComponentScan'ed by Spring to allow for creating custom Spring beans # custom-bean-packages: # custom-interceptor-classes: # custom-provider-classes: # store_meta_source_information: NONE # bundle_batch_pool_size: 10 # bundle_batch_pool_max_size: 50 # ------------------------------------------------------------------------------- # N. Logging # ------------------------------------------------------------------------------- # logger: # error_format: "ERROR - ${requestVerb} ${requestUrl}" # format: >- # Path[${servletPath}] Source[${requestHeader.x-forwarded-for}] # Operation[${operationType} ${operationName} ${idOrResourceName}] # UA[${requestHeader.user-agent}] Params[${requestParameters}] # ResponseEncoding[${responseEncodingNoDefault}] # log_exceptions: true # name: fhirtest.access # ------------------------------------------------------------------------------- # O. Storage / Pagination / Caching # ------------------------------------------------------------------------------- # max_binary_size: 104857600 # max_page_size: 200 # retain_cached_searches_mins: 60 # reuse_cached_search_results_millis: 60000 # validation: # requests_enabled: true # responses_enabled: true # binary_storage_enabled: true # binary_storage_mode: FILESYSTEM # binary_storage_filesystem_base_directory: /binstore # When binary_storage_mode is FILESYSTEM and this value is not set, # the starter defaults to 102400 bytes so smaller binaries stay inline. inline_resource_storage_below_size: 4000 # ------------------------------------------------------------------------------- # P. Remote Terminology Service (disabled by default) # ------------------------------------------------------------------------------- # remote_terminology_service: # all: # system: "*" # url: "https://tx.fhir.org/r4/" # snomed: # system: "http://snomed.info/sct" # url: "https://tx.fhir.org/r4/" # loinc: # system: "http://loinc.org" # url: "https://hapi.fhir.org/baseR4/" # ------------------------------------------------------------------------------- # Q. Subscriptions (disabled by default) # ------------------------------------------------------------------------------- # subscription: # resthook_enabled: true # websocket_enabled: false # polling_interval_ms: 5000 # immediately_queued: false # email: # from: some@test.com # host: google.com # port: # username: # password: # auth: # startTlsEnable: # startTlsRequired: # quitWait: # ------------------------------------------------------------------------------- # R. LastN (analytics) # ------------------------------------------------------------------------------- # lastn_enabled: true # ------------------------------------------------------------------------------- # S. Testers (webui) # ------------------------------------------------------------------------------- tester: home: name: Local Tester server_address: 'http://localhost:8080/fhir' refuse_to_fetch_third_party_urls: false fhir_version: R4