createObservation
Generate and store new medical observations, such as lab results or vital signs, by providing patient ID, observation code, and required details using the Medplum MCP Server.
Instructions
Creates a new observation (lab result, vital sign, etc.). Requires patient ID and code.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| code | Yes | The code representing what was observed (LOINC, SNOMED CT, etc.). | |
| encounterId | No | The encounter this observation is associated with. Optional. | |
| patientId | Yes | The ID of the patient this observation is for. | |
| status | Yes | The status of the observation. | |
| valueQuantity | No | Numeric value of the observation. Optional. | |
| valueString | No | String value of the observation. Optional. |
Implementation Reference
- src/tools/observationUtils.ts:91-163 (handler)The main handler function that implements the createObservation tool logic. It constructs an Observation FHIR resource from the input arguments, performs validations, handles ID-to-reference conversions, and calls medplum.createResource to persist it.export async function createObservation(args: CreateObservationArgs): Promise<Observation> { await ensureAuthenticated(); // Handle subjectId conversion for convenience let subject = args.subject; if (args.subjectId && !subject) { subject = { reference: `Patient/${args.subjectId}` }; } // Handle encounterId conversion for convenience let encounter = args.encounter; if (args.encounterId && !encounter) { encounter = { reference: `Encounter/${args.encounterId}` }; } // Handle performerIds conversion for convenience let performer = args.performer; if (args.performerIds && !performer) { performer = args.performerIds.map(id => ({ reference: `Practitioner/${id}` })); } if (!subject?.reference) { throw new Error('Patient reference is required to create an observation.'); } if (!args.code || !args.code.coding || args.code.coding.length === 0) { throw new Error('Observation code with at least one coding is required.'); } if (!args.status) { throw new Error('Observation status is required.'); } if ( args.valueQuantity === undefined && args.valueCodeableConcept === undefined && args.valueString === undefined && args.valueBoolean === undefined && args.valueInteger === undefined && args.valueRange === undefined && args.valueRatio === undefined && args.valueSampledData === undefined && args.valueTime === undefined && args.valueDateTime === undefined && args.valuePeriod === undefined ) { throw new Error('At least one value field must be provided (valueQuantity, valueCodeableConcept, valueString, valueBoolean, valueInteger, valueRange, valueRatio, valueSampledData, valueTime, valueDateTime, or valuePeriod).'); } const observationResource: Observation = { resourceType: 'Observation', status: args.status, code: args.code, subject: subject, encounter: encounter, effectiveDateTime: args.effectiveDateTime, effectivePeriod: args.effectivePeriod, issued: args.issued || new Date().toISOString(), performer: performer, valueQuantity: args.valueQuantity, valueCodeableConcept: args.valueCodeableConcept, valueString: args.valueString, valueBoolean: args.valueBoolean, valueInteger: args.valueInteger, valueRange: args.valueRange, valueRatio: args.valueRatio, valueSampledData: args.valueSampledData, valueTime: args.valueTime, valueDateTime: args.valueDateTime, valuePeriod: args.valuePeriod, bodySite: args.bodySite, method: args.method, referenceRange: args.referenceRange, note: args.note ? [{ text: args.note }] : undefined, interpretation: args.interpretation, identifier: args.identifier ? [{ system: args.identifier.system, value: args.identifier.value }] : undefined, }; if (args.component) { observationResource.component = args.component; } return medplum.createResource<Observation>(observationResource); }
- src/tools/observationUtils.ts:5-35 (schema)TypeScript interface defining the input arguments for the createObservation function, providing type safety and documentation for the expected parameters.export interface CreateObservationArgs { status: Observation['status']; code: CodeableConcept; subject?: Reference<Patient>; // Made optional since tests use subjectId subjectId?: string; // For convenience in tests - will be converted to subject reference encounter?: Reference<Encounter>; encounterId?: string; // For convenience in tests - will be converted to encounter reference effectiveDateTime?: string; effectivePeriod?: Period; issued?: string; performer?: Reference<Practitioner>[]; performerIds?: string[]; // For convenience in tests - will be converted to performer references valueQuantity?: Quantity; valueString?: string; valueBoolean?: boolean; valueCodeableConcept?: CodeableConcept; valueInteger?: number; valueRange?: Range; valueRatio?: Ratio; valueSampledData?: SampledData; valueTime?: string; valueDateTime?: string; valuePeriod?: Period; bodySite?: CodeableConcept; method?: CodeableConcept; component?: any[]; interpretation?: CodeableConcept[]; note?: string; referenceRange?: any[]; identifier?: { system?: string; value: string }; }
- src/index.ts:459-492 (registration)MCP tool registration including the name, description, and input schema for the createObservation tool, used by the ListToolsRequest handler.name: "createObservation", description: "Creates a new observation (lab result, vital sign, etc.). Requires patient ID and code.", inputSchema: { type: "object", properties: { patientId: { type: "string", description: "The ID of the patient this observation is for.", }, code: { type: "string", description: "The code representing what was observed (LOINC, SNOMED CT, etc.).", }, valueQuantity: { type: "number", description: "Numeric value of the observation. Optional.", }, valueString: { type: "string", description: "String value of the observation. Optional.", }, status: { type: "string", description: "The status of the observation.", enum: ["registered", "preliminary", "final", "amended", "corrected", "cancelled"], }, encounterId: { type: "string", description: "The encounter this observation is associated with. Optional.", }, }, required: ["patientId", "code", "status"], }, },
- src/index.ts:968-968 (registration)Mapping of the createObservation function to the tool name in the toolMapping object, used by the CallToolRequest handler to execute the tool.createObservation,
- src/index.ts:39-43 (registration)Import statement bringing the createObservation handler into the main index file for registration.createObservation, getObservationById, updateObservation, searchObservations, } from './tools/observationUtils.js';