Skip to main content
Glama
metadata.ts12.6 kB
// SPDX-FileCopyrightText: Copyright Orangebot, Inc. and Medplum contributors // SPDX-License-Identifier: Apache-2.0 import type { InternalTypeSchema } from '@medplum/core'; import { concatUrls, ContentType, getAllDataTypes, getSearchParameters, HTTP_TERMINOLOGY_HL7_ORG, isResourceType, MEDPLUM_VERSION, } from '@medplum/core'; import type { CapabilityStatement, CapabilityStatementRest, CapabilityStatementRestResource, CapabilityStatementRestResourceOperation, CapabilityStatementRestResourceSearchParam, CapabilityStatementRestSecurity, ResourceType, } from '@medplum/fhirtypes'; import { getConfig } from '../config/loader'; import type { MedplumServerConfig } from '../config/types'; /** * The base CapabilityStatement that seeds the server generated statement. */ const baseStmt: CapabilityStatement = { resourceType: 'CapabilityStatement', id: 'medplum-server', version: MEDPLUM_VERSION, name: 'MedplumCapabilityStatement', title: 'Medplum Capability Statement', status: 'active', date: new Date().toISOString(), publisher: 'Medplum', contact: [ { telecom: [ { system: 'url', value: 'https://www.medplum.com', }, ], }, ], description: 'Medplum FHIR Capability Statement', jurisdiction: [ { coding: [ { system: 'urn:iso:std:iso:3166', code: 'US', display: 'United States of America', }, ], }, ], kind: 'instance', instantiates: [ 'http://hl7.org/fhir/us/core/CapabilityStatement/us-core-server', 'http://hl7.org/fhir/uv/bulkdata/CapabilityStatement/bulk-data', ], implementationGuide: ['http://hl7.org/fhir/uv/fhircast/ImplementationGuide/hl7.fhir.uv.fhircast|3.0.0'], fhirVersion: '4.0.1', format: ['json'], patchFormat: [ContentType.JSON_PATCH], }; /** * A list of profiles that represent different use cases supported by the system. * * For a server, "supported by the system" means the system hosts/produces a set of resources that are conformant to a * particular profile, and allows clients that use its services to search using this profile and to find appropriate * data. For a client, it means the system will search by this profile and process data according to the guidance * implicit in the profile. * * See: https://www.hl7.org/fhir/capabilitystatement-definitions.html#CapabilityStatement.rest.resource.supportedProfile */ const supportedProfiles: Record<string, string[]> = { AllergyIntolerance: ['http://hl7.org/fhir/us/core/StructureDefinition/us-core-allergyintolerance'], CarePlan: ['http://hl7.org/fhir/us/core/StructureDefinition/us-core-careplan'], CareTeam: ['http://hl7.org/fhir/us/core/StructureDefinition/us-core-careteam'], Condition: [ 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-condition-encounter-diagnosis', 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-condition-problems-health-concerns', ], Coverage: ['http://hl7.org/fhir/us/core/StructureDefinition/us-core-coverage'], Device: ['http://hl7.org/fhir/us/core/StructureDefinition/us-core-implantable-device'], DiagnosticReport: [ 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-diagnosticreport-note', 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-diagnosticreport-lab', ], DocumentReference: ['http://hl7.org/fhir/us/core/StructureDefinition/us-core-documentreference'], Encounter: ['http://hl7.org/fhir/us/core/StructureDefinition/us-core-encounter'], Goal: ['http://hl7.org/fhir/us/core/StructureDefinition/us-core-goal'], Immunization: ['http://hl7.org/fhir/us/core/StructureDefinition/us-core-immunization'], Location: ['http://hl7.org/fhir/us/core/StructureDefinition/us-core-location'], Medication: ['http://hl7.org/fhir/us/core/StructureDefinition/us-core-medication'], MedicationDispense: ['http://hl7.org/fhir/us/core/StructureDefinition/us-core-medicationdispense'], MedicationRequest: ['http://hl7.org/fhir/us/core/StructureDefinition/us-core-medicationrequest'], Observation: [ 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-blood-pressure', 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-bmi', 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-head-circumference', 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-body-height', 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-body-weight', 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-body-temperature', 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-heart-rate', 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-respiratory-rate', 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-observation-clinical-result', 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-observation-occupation', 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-observation-pregnancyintent', 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-observation-pregnancystatus', 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-observation-screening-assessment', 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-observation-sexual-orientation', 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-treatment-intervention-preference', 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-care-experience-preference', 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-average-blood-pressure', 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-smokingstatus', 'http://hl7.org/fhir/us/core/StructureDefinition/pediatric-weight-for-height', 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-observation-lab', 'http://hl7.org/fhir/us/core/StructureDefinition/pediatric-bmi-for-age', 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-pulse-oximetry', 'http://hl7.org/fhir/us/core/StructureDefinition/head-occipital-frontal-circumference-percentile', 'http://hl7.org/fhir/StructureDefinition/heartrate', 'http://hl7.org/fhir/StructureDefinition/bodyheight', 'http://hl7.org/fhir/StructureDefinition/bp', 'http://hl7.org/fhir/StructureDefinition/bodyweight', 'http://hl7.org/fhir/StructureDefinition/bodytemp', 'http://hl7.org/fhir/StructureDefinition/resprate', ], Organization: ['http://hl7.org/fhir/us/core/StructureDefinition/us-core-organization'], Patient: ['http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient'], Practitioner: ['http://hl7.org/fhir/us/core/StructureDefinition/us-core-practitioner'], PractitionerRole: ['http://hl7.org/fhir/us/core/StructureDefinition/us-core-practitionerrole'], Procedure: ['http://hl7.org/fhir/us/core/StructureDefinition/us-core-procedure'], Provenance: ['http://hl7.org/fhir/us/core/StructureDefinition/us-core-provenance'], RelatedPerson: ['http://hl7.org/fhir/us/core/StructureDefinition/us-core-relatedperson'], ServiceRequest: ['http://hl7.org/fhir/us/core/StructureDefinition/us-core-servicerequest'], Specimen: ['http://hl7.org/fhir/us/core/StructureDefinition/us-core-specimen'], }; const supportedOperations: Record<string, CapabilityStatementRestResourceOperation[]> = { Group: [ { name: 'export', definition: 'http://hl7.org/fhir/uv/bulkdata/OperationDefinition/group-export', }, ], }; /** * A list of the advanced search parameters that are FHIR Search Result Parameters applicable to the server. * See: https://www.hl7.org/fhir/search.html#modifyingresults */ const supportedSearchParams: CapabilityStatementRestResourceSearchParam[] = [ { name: '_sort', definition: 'https://www.hl7.org/fhir/search.html#_sort', type: 'string', }, { name: '_total', definition: 'https://www.hl7.org/fhir/search.html#_total', type: 'string', }, { name: '_count', definition: 'https://www.hl7.org/fhir/search.html#_count', type: 'number', }, { name: '_summary', definition: 'https://www.hl7.org/fhir/search.html#_summary', type: 'token', }, { name: '_elements', definition: 'https://www.hl7.org/fhir/search.html#_elements', type: 'string', }, ]; let capabilityStatement: CapabilityStatement | undefined = undefined; export function getCapabilityStatement(): CapabilityStatement { if (!capabilityStatement) { capabilityStatement = buildCapabilityStatement(); } return capabilityStatement; } function buildCapabilityStatement(): CapabilityStatement { const name = 'medplum'; const version = MEDPLUM_VERSION; const config = getConfig(); const baseUrl = config.baseUrl; const fhirBaseUrl = concatUrls(baseUrl, 'fhir/R4/'); const metadataUrl = concatUrls(fhirBaseUrl, 'metadata'); return { ...baseStmt, url: metadataUrl, software: { name, version, }, implementation: { description: name, url: fhirBaseUrl, }, rest: buildRest(config), }; } function buildRest(config: MedplumServerConfig): CapabilityStatementRest[] { return [ { mode: 'server', security: buildSecurity(config), resource: buildResourceTypes(), interaction: [{ code: 'transaction' }, { code: 'batch' }], searchParam: supportedSearchParams, extension: [ // See: https://build.fhir.org/ig/HL7/fhircast-docs/CapabilityStatement-fhircast-capabilitystatement-example.json { extension: [ { url: 'hub.url', valueUrl: `${config.baseUrl}fhircast/STU3`, }, ], url: 'http://hl7.org/fhir/uv/fhircast/StructureDefinition/fhircast-configuration-extension', }, ], }, ]; } function buildSecurity(config: MedplumServerConfig): CapabilityStatementRestSecurity { return { cors: true, service: ['OAuth', 'Basic', 'SMART-on-FHIR'].map((service) => ({ coding: [ { system: HTTP_TERMINOLOGY_HL7_ORG + '/CodeSystem/restful-security-service', code: service, }, ], })), extension: [ { url: 'http://fhir-registry.smarthealthit.org/StructureDefinition/oauth-uris', extension: [ { url: 'authorize', valueUri: config.authorizeUrl, }, { url: 'token', valueUri: config.tokenUrl, }, ], }, ], }; } function buildResourceTypes(): CapabilityStatementRestResource[] { return Object.entries(getAllDataTypes()) .filter( ([resourceType, typeSchema]) => isResourceType(resourceType) && typeSchema.url?.startsWith('http://hl7.org/fhir/StructureDefinition/') && typeSchema.version === '4.0.1' ) .map( ([resourceType, typeSchema]) => ({ type: resourceType as ResourceType, profile: typeSchema.url, supportedProfile: supportedProfiles[resourceType] || undefined, interaction: [ { code: 'read' }, // Read the current state of the resource. { code: 'vread' }, // Read the state of a specific version of the resource. { code: 'update' }, // Update an existing resource by its id. { code: 'patch' }, // Update an existing resource by posting a set of changes to it. { code: 'delete' }, // Delete a resource. { code: 'history-instance' }, // Retrieve the change history for a particular resource. { code: 'create' }, // Create a new resource with a server assigned id. { code: 'search-type' }, // Search all resources of the specified type based on some filter criteria. ], versioning: 'versioned', readHistory: true, updateCreate: false, conditionalCreate: true, conditionalUpdate: true, conditionalRead: 'not-supported', conditionalDelete: 'single', referencePolicy: ['literal', 'logical', 'local'], searchParam: buildSearchParameters(typeSchema), operation: supportedOperations[resourceType], }) satisfies CapabilityStatementRestResource ); } function buildSearchParameters( typeSchema: InternalTypeSchema ): CapabilityStatementRestResourceSearchParam[] | undefined { const searchParams = getSearchParameters(typeSchema.name); if (!searchParams) { return undefined; } const entries = Object.values(searchParams); if (entries.length === 0) { return undefined; } return entries.map((param: any) => ({ name: param.code, definition: param.url, type: param.type, })); }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/medplum/medplum'

If you have feedback or need assistance with the MCP directory API, please join our Discord server