Open-source clinical agent infrastructure

Read the chart broadly. Write only what a human approved.

Last EHR is the agent layer for a headless FHIR EHR. It reads the chart broadly: 25 of US Core's 27 readable resource types, across 23 sections, following references. And it is built so the agent cannot claim something isn't in the chart when it never looked. Every write is a proposal: the exact resource shown, an explicit human decision, committed exactly as reviewed, recorded with what created it. That write half is a small protocol with a conformance suite, and the live demo is its reference implementation. Five FHIR backends, one interface.

Proposal → Decision → Commit → AuditApproval-Gated Agent Writes on FHIR, v0.1 draft

25 of US Core's 27 readable types, counted in the openCannot report an absence it never checked forOpen protocol, v0.1 draft, criticism invitedFive FHIR backends behind one interface
Inspect the implementation
Clinical action ledgerwrite / paused

Agent request

record_observation({
  patientId: "<synthetic-patient-id>",
  label: "Heart rate",
  value: 72,
  unit: "bpm"
})

needsApproval: true

  1. 01IntentRecord heart rate: 72 bpm
  2. 02ProposalFHIR Observation / not persisted
  3. 03DecisionExplicit reviewer approval required
  4. 04Commit + auditBackend policy enforced; AIAST-labeled
ResourceFHIR Observation
PersistenceBlocked pending review
AuthorityFHIR backend policy

The UI is not the authorization layer. It makes the proposed change inspectable before the backend receives it.

The safety contract

A clinical write is a workflow, not an API side effect.

Last EHR does not claim to replace backend policy or clinical judgment. It gives the agent a small, inspectable surface and makes the point of human review impossible to miss.

Read the approval model
01

Read a bounded chart surface

Search and chart reads are explicit tools over FHIR. The backend remains the system of record and access-control boundary.

02

Represent intent as a proposal

A note, observation, or follow-up task is shown as a concrete FHIR-shaped change, not hidden as an agent side effect.

03

Require a human decision

The write tool pauses. A reviewer can inspect, approve, or cancel before anything reaches the chart — and every ambiguous outcome fails closed.

04

Commit what was reviewed, attributably

Nothing beyond the reviewed proposal saves except mechanical metadata. Every agent write carries the standard AIAST security label, with optional Provenance recording an author agent and a human verifier.

System of recordFHIR backend
Agent layerInspectable proposal
DecisionReview + policy
The backend still decides what the signed-in identity can read or write. The local HAPI routes are synthetic evaluation tools, not an authorization model.

One protocol, two running bindings

Not designed on paper. Extracted from running code.

Approval-Gated Agent Writes on FHIR is a v0.1 draft of the layer between “the agent wants to write” and “the chart changed”: Proposal → Decision → Commit → Audit. CDS Hooks owns EHR-initiated suggestions, the AI Transparency IG owns after-the-fact provenance, SMART owns identity, MCP owns transport — this names the unclaimed step in the middle, reusing their vocabulary where it fits. Independent implementations and criticism are invited.

Web approval card

The write tool declares needsApproval; the SDK pauses before execute; a card renders the exact fields plus a FHIR-shaped preview; an explicit approve or cancel resumes the flow.

Same semantics, different host

See it live in the demo

MCP elicitation

A host that cannot render the approval prompt is never offered a write tool. Each call pauses on an elicitation showing the exact fields with one approve boolean; only an explicit approval commits.

Same semantics, different host

Read the MCP binding

A safety claim you can test from outside.

The conformance suite is an independent MCP client with a scripted reviewer. It spawns an implementing server fresh for every scenario and verifies each outcome against the FHIR store with its own reads — never the implementation's word for it. CI runs it in strict mode against this repository's own server on every pull request and merge.

It proves gate mechanics, not clinical correctness or authorization — the report says exactly which is which.

Run it against your implementation
Test the claimstrict mode in CI
$ npx @lastehr/agent-write-conformance \
    --server "node dist/my-mcp-server.js" \
    --manifest awp-manifest.json \
    --fhir-base-url http://localhost:8080/fhir \
    --confirm-synthetic --strict
  • Capability gate: no approval surface, no write tools
  • Proposal before persistence, probed during deliberation
  • Approve, decline, cancel, and transport failure — every non-approval saves nothing
  • Commit fidelity: the reviewed values committed, exactly once
  • Audit: AIAST labels and author/verifier Provenance (strict mode)

MCP, deliberately constrained

MCP should inspect, not quietly write.

The published package is read-only by default, with bounded chart reads and one write mode that is proposal-shaped: the client renders the exact fields and a human approves each write. The checkout Local Lab lets a developer inspect the bounded read surface against four synthetic HAPI charts before connecting a real project.

Scope worth stating: the MCP package targets Medplum or the local HAPI stack, which is narrower than the web app on purpose. The five verified backends below all work through the web agent.

No FHIR credential for the Local Lab server.

Fixture-only data on loopback HAPI.

Your client keeps its own model account.

Read the MCP boundary
MCP access pathsread-only by default

Use with Medplum

$ npx -y @lastehr/mcp init --client claude-code

Prints a client registration command for a least-privilege Medplum token. By default the package exposes only reads.

Inspect locally

$ npm run mcp:demo -- --client claude-code

Starts loopback HAPI, resets synthetic fixtures, and prints a direct registration command without FHIR credentials.

Tool manifest

Read tools ship by default. The write tools exist only behind LASTEHR_MCP_WRITES=proposal, are offered only to clients that can render the approval prompt, and every write is a human-approved proposal — never an arbitrary endpoint.

Read-only stays the default; every write needs a human approval.
  • search_patientsFind a seeded synthetic patient by name.READ
  • show_patient_infoOpen one fixture-restricted chart by id.READ
  • add_notePropose a note; a human approves the exact text per action.PROPOSAL
  • record_observationPropose a vital or lab value behind the same elicitation gate.PROPOSAL
  • create_taskPropose a follow-up task with an optional due date.PROPOSAL
Published package: @lastehr/mcpSupport matrix →

Three useful first moves

Start with evidence, not a sales call.

The project is built for people who need to inspect the safety boundary before they bring an agent anywhere near a real chart. Pick the path that matches the question you have today.

01

See the decision point

Use the live synthetic demo to watch a clinical write become a visible proposal before it is saved.

Open /demoOpen the demo
02

Test an implementation

Run the conformance suite against any MCP stdio server implementing the write profile: a scripted reviewer plus independent FHIR verification.

npx @lastehr/agent-write-conformanceRead the conformance guide
03

Run the Safety Eval

Create a scrubbed report for proposal, approval, denial, chart association, and cleanup on a disposable target.

npm run evalRead the evaluator

An integration should be able to explain itself

Make compatibility a testable claim.

Last EHR keeps the extension point small: a FHIR backend contract, an executable adapter starter, and real HAPI integration coverage. The Safety Eval runs on those same disposable synthetic workflows and writes a scrubbed report, not a broad marketing badge.

Five backends run through it today, and what each one is verified for is published rather than averaged into a logo wall:

  • MedplumSupported. The authenticated path. Medplum owns identity, tenancy, AccessPolicy, and audit logs.
  • HAPI FHIRLocal evaluation. The repository's Docker Compose stack. No auth, loopback-bound, synthetic data on one machine.
  • OystehrSynthetic evaluation. OAuth2 M2M against a developer-tier project. The only backend so far that honors server-side session isolation with no client-side fallback.
  • AidboxSynthetic evaluation. HTTP Basic from an Aidbox Client. Needs a box you own and seed; its AccessPolicy stays the security boundary.
  • Firely ServerSynthetic evaluation. Verified against the public synthetic sandbox, which is shared and periodically wiped, so it is unsuitable for a public demo.

Adding one is a small class plus contract tests. Thesupport matrixstates what “verified” means for each.

Read the adapter contract
Proof surfacesynthetic / CI-backed
01
Web agentEvery write tool is proposal-shaped and approval-gated.
verified
02
Read coverageCounted in the open against US Core, with the ceiling and the deliberate exclusions published rather than implied.
verified
03
MCP write profileElicitation-gated proposals behind an explicit opt-in; write tools are offered only to approval-capable clients.
verified
04
Conformance suiteAn independent client drives approve, deny, cancel, and failure paths, verifying the chart with its own reads — dogfooded in CI in strict mode.
verified
05
Adapter seamA reusable FHIR REST baseline and contract harness make the next backend testable.
verified
06
Safety EvalA disposable synthetic workflow report proves approval, denial, chart association, and cleanup mechanics.
verified
The evaluator proves deterministic workflow mechanics, not clinical correctness, HIPAA compliance, or backend RBAC.

Built in the open

Inspect the source before you trust the promise.

Last EHR is Apache-2.0. The code, safety notes, local paths, and support boundaries are public. A future managed offering is optional; the inspectable core is the point.

Not a medical device, a substitute for clinical judgment, an authorization layer, or a HIPAA-ready deployment by default.

Hosted updates

Join only for future managed-service news. Open-source updates ship in the repository first.