Open-source clinical agent infrastructure

Make every AI chart write a reviewable proposal.

Last EHR defines and tests a small protocol for agent-initiated FHIR writes: show the exact proposed resource, require an explicit human decision, commit exactly what was reviewed, and record what created it. The live demo is its reference implementation.

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

Open protocol, v0.1 draft — criticism invitedTwo running bindings: web and MCPIndependent conformance suite, dogfooded in CI
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 — bounded chart reads over Medplum or the local HAPI stack — and its only write mode 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.

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.

Read the adapter contract
Proof surfacesynthetic / CI-backed
01
Web agentThree write tools are proposal-shaped and approval-gated.
verified
02
MCP write profileElicitation-gated proposals behind an explicit opt-in; write tools are offered only to approval-capable clients.
verified
03
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
04
Adapter seamA reusable FHIR REST baseline and contract harness make the next backend testable.
verified
05
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.

Documentation as an operating manual

Make a responsible technical decision faster.

Each guide names the path, the support boundary, and what still needs proof. The docs are a product surface, not a dump of API notes after the fact.

Open the docs hub

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.