Spaces | Medplum
What You Can Do With Spaces
Spaces is the in-app AI assistant in Medplum Provider. A user types a question in natural language; under the hood a chain of Medplum bots translates the question into FHIR API calls, executes them against the project, summarizes the results in the chat, and optionally renders a generated chart inside the same view.
The assistant's behavior – what it says, what it refuses, which FHIR strategies it uses, how it summarizes, what charts it favors – is determined by three Communication resources that you author for your deployment. Spaces ships without canonical prompts on purpose: the right behavior depends on what your clinic plans to use the feature for. See Author System Prompt Communications below.
The feature is reachable at /Spaces/Communication in the Provider app. It is gated on the project having both the ai and bots features enabled.
Typical Prompts
The translator bot can issue any FHIR request the requester's AccessPolicy permits, so the practical capability surface is broad. Typical prompts fall into a few categories:
- Search and lookup – "Find the patient John Smith." "Which patients are scheduled with Dr. Chen this week?"
- Clinical summary – "Summarize Maria Garcia's last three encounters." "What medications is this patient on?"
- Visualize trends – "Show a growth chart for this patient." "Plot hemoglobin A1c over the last two years."
- Operational reporting – "Chart provider utilization across the clinic for the past month." "How many lab orders did we place last week?"
- Schedule and tasks – "Schedule a follow-up with Dr. Patel next Tuesday at 10am." "Create a task to fax the imaging report to the referring provider."
- Orders and updates – "Order a CBC for this patient." "Place a referral to cardiology." "Update the patient's phone number to 555-0142."
The first four bullets are read-only and end at the summary bot. The visualization and reporting prompts additionally invoke the visualizer bot to render an interactive chart in the side panel. The last two bullets trigger live FHIR writes through the same loop.
How Spaces Works
Spaces is not a single AI call. Each user prompt drives a short pipeline of bots and a tool-use loop:
- tool_calls + visualize flag
- loop up to 10 iterations
- no tool calls
- visualize = false
- visualize = true
Important Details
- The Provider UI, not the bots, executes the FHIR requests that the translator suggests. Every request runs under the signed-in user's access policies, so the assistant can never read or write resources the user could not access directly.
- The bots are the only thing that talks to OpenAI. The browser never sees the OpenAI API key. All AI traffic flows through the server-side
$aioperation, which reads the key from project secrets. - Conversation history is persisted as
Communicationresources, so transcripts are searchable, auditable, and survive a page reload.
Prerequisites
Enable Project Features
Spaces requires the ai and bots features on your Medplum project. Both are disabled by default. Contact info@medplum.com to enable them on your account; project administrators cannot toggle these features directly.
Configure The OpenAI API Key
Add your OpenAI key as a project secret named OPENAI_API_KEY. The $ai operation reads it from the project on every call and forwards it to OpenAI's chat completions endpoint. It is never sent to the client.
Deploy The Spaces Bots
Spaces depends on three bots that ship under examples/medplum-demo-bots/src/spaces-bots and are already registered in that project's medplum.config.json. The Provider UI resolves each one by Identifier (system https://www.medplum.com/bots), so the identifier values below are load-bearing.
| Identifier Value | Source File | Role |
|---|---|---|
ai-fhir-request-tools |
fhir-translator-bot.ts |
Translator. Emits fhir_request tool calls and a visualize flag. |
ai-resource-summary-sse |
fhir-summary-bot.ts |
Streaming summary bot (Server-Sent Events). |
ai-component-generator-sse |
fhir-visualizer-bot.ts |
Streaming Recharts / Mantine Chart() JSX generation. |
Author System Prompt Communications
Each of the three Spaces bots loads its system prompt from a Communication resource at request time, not from code. These prompts are operator-authored content. They decide what Spaces does in your clinic: its tone, what it refuses, which FHIR-call strategies the translator prefers, how aggressively the summary bot narrates, which chart types the visualizer reaches for. Treat writing them as part of building the feature, not as a setup step that copies a canned recipe.
| Bot | Prompt Communication identifier.value |
Payload Shape |
|---|---|---|
ai-fhir-request-tools |
ai-fhir-request-tools |
Both payloads are required. payload[0] is the system prompt. payload[1] is a profile-context template; any {{ref}} is replaced at request time with the requester's reference string. |
ai-resource-summary-sse |
ai-resource-summary-sse |
payload[0] is the system prompt. No profile-context template. |
ai-component-generator-sse |
ai-component-generator-sse |
payload[0] is the system prompt. No profile-context template. |
Example Setup for Communications
await medplum.createResource<Communication>({
resourceType: 'Communication',
status: 'completed',
identifier: [{ system: 'http://medplum.com/ai-spaces', value: 'ai-fhir-request-tools' }],
payload: [
{
contentString: [
'You are a FHIR data assistant for Medplum.',
'Use the fhir_request tool for every FHIR operation - never invent results.',
'For updates, first GET the resource, then PUT the modified full resource.',
'Set visualize=true on the tool call when the result should be a chart',
'(for example trends or values over time).',
].join('\n'),
},
{
contentString: 'The requester is {{ref}}. Scope queries to data they are entitled to see.',
},
],
});
Security And Cost
- The OpenAI API key lives only in
Project.secret. The browser cannot read it, and bots receive it only inside their handler scope. - AccessPolicy applies to every FHIR request the loop executes. The assistant cannot read or write resources the requester is not entitled to. Audit-sensitive deployments should also restrict which
Practitioneraccounts have theaifeature exposed in their session. - Every loop iteration is one OpenAI call. A user asking a multi-hop question can drive five to ten model calls per prompt. Monitor your OpenAI usage dashboard and consider rate-limiting the bot endpoints in production.
- All Spaces activity is recorded as standard FHIR
AuditEventresources, the same way every other Medplum write is.