Skip to content

Connect drchrono to Claude: Automate Clinical Notes and Scheduling

Learn how to build and configure a managed MCP server to connect drchrono to Claude. Automate clinical note generation, lab ordering, and patient scheduling using secure AI agents.

Nachi Raman Nachi Raman · · 10 min read
Connect drchrono to Claude: Automate Clinical Notes and Scheduling

If your team needs to connect drchrono to Claude to automate clinical note generation, streamline patient scheduling, or manage lab orders, you need a Model Context Protocol (MCP) server. This server acts as the translation layer between Claude's tool calls and drchrono's REST API. You can either build and maintain this infrastructure yourself, or use a managed integration platform like Truto to dynamically generate a secure, authenticated MCP server URL. If your team uses ChatGPT, check out our guide on /connect-drchrono-to-chatgpt-sync-patient-records-and-lab-workflows/ or explore our broader architectural overview on /connect-drchrono-to-ai-agents-manage-billing-and-medical-records/.

Giving a Large Language Model (LLM) read and write access to a specialized Electronic Health Record (EHR) system like drchrono is a serious engineering challenge. You have to handle strict OAuth 2.0 token lifecycles, map massive JSON schemas for clinical data to MCP tool definitions, and deal with drchrono's highly normalized data structures. Every time drchrono updates an endpoint or changes a billing code field, you have to update your server code, redeploy, and test the integration.

This guide breaks down exactly how to use Truto to generate a secure, managed MCP server for drchrono, connect it natively to Claude, and execute complex clinical management workflows using natural language.

The Engineering Reality of the drchrono API

A custom MCP server is a self-hosted integration layer. While the open MCP standard provides a predictable way for models to discover tools, the reality of implementing it against specialized healthcare APIs is painful. drchrono is built to manage everything from clinical charting and e-prescribing to complex medical billing. Its API directly reflects that complexity.

If you decide to build a custom drchrono MCP server, here are the specific integration challenges you will face:

Discrete Clinical Note Fields vs. Monolithic Text An LLM natively generates blocks of text. However, you cannot simply push a monolithic text block to a single notes field in drchrono. Clinical notes in drchrono are highly structured and templated. To update a patient's chart, you must interact with the clinical_note_field_values endpoint. This requires the LLM to know the exact appointment ID and the specific clinical_note_field ID (e.g., the specific ID for "Chief Complaint" vs. "Assessment and Plan"). You must map these relational IDs accurately, or the data will be orphaned or appended to the wrong section of the patient's chart.

Multi-Step Lab Order Orchestration Ordering a lab in drchrono via the API is not a single CRUD operation. You cannot simply pass "Order CBC" to an endpoint. A proper lab order creation (create_a_drchrono_lab_order) requires the patient ID, the doctor ID, and the sublab ID. Furthermore, if you are ingesting results, it requires creating the lab order, pushing result PDFs via the lab_documents endpoint, and sending discrete structured data via lab_results. An LLM cannot intuit this stateful, multi-step orchestration on its own. It requires strictly defined MCP tools with crystal-clear schema descriptions.

Strict Appointment State Management The drchrono appointments endpoint is heavily normalized. Searching for appointments requires specific parameter formats (e.g., date, since, or occurred_since). Modifying an appointment requires knowing the exact exam_room ID and office ID. Building an MCP server means you have to write logic that safely flattens these complex query parameters into a flat input namespace that Claude can reliably utilize without hallucinating foreign keys.

Creating the drchrono MCP Server

Instead of building a Node.js or Python server from scratch to handle drchrono's OAuth flow and schema mapping, you can use Truto to generate a managed MCP server dynamically. Truto translates drchrono's existing API documentation into standardized JSON-RPC tools instantly.

You can create the MCP server in two ways: via the Truto UI for rapid prototyping, or via the Truto API for programmatic deployment.

Method 1: Via the Truto UI

If you are setting this up for internal team use or testing, the UI is the fastest path.

  1. Navigate to the Integrated Accounts page in your Truto dashboard and select your authenticated drchrono connection.
  2. Click the MCP Servers tab.
  3. Click Create MCP Server.
  4. Select your desired configuration (e.g., name the server "drchrono Clinical Ops", select allowed methods like read and write, and apply tags if you only want specific resource groups exposed).
  5. Click Save and copy the generated MCP server URL (e.g., https://api.truto.one/mcp/a1b2c3d4e5f6...).

Method 2: Via the Truto API

For production use cases where you are provisioning AI agents for multiple clinical teams programmatically, you should generate the MCP server via the Truto API. This creates a secure, tokenized URL backed by a database record and Cloudflare KV storage.

Make a POST request to the /integrated-account/:id/mcp endpoint:

curl -X POST https://api.truto.one/integrated-account/{integrated_account_id}/mcp \
  -H "Authorization: Bearer YOUR_TRUTO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "drchrono Autonomous Charting Agent",
    "config": {
      "methods": ["read", "write"],
      "require_api_token_auth": false
    },
    "expires_at": "2025-12-31T23:59:59Z"
  }'

The API will return a response containing the secure MCP URL:

{
  "id": "mcp_8a9b0c1d2e",
  "name": "drchrono Autonomous Charting Agent",
  "config": { 
    "methods": ["read", "write"], 
    "require_api_token_auth": false 
  },
  "expires_at": "2025-12-31T23:59:59Z",
  "url": "https://api.truto.one/mcp/f8e7d6c5b4a3..."
}

This URL contains a hashed cryptographic token. It is a fully self-contained, authenticated JSON-RPC 2.0 endpoint that Claude can communicate with directly.

Connecting the MCP Server to Claude

Once you have your Truto MCP URL, you need to connect it to your AI interface. Truto's servers are universally compatible with any client that speaks the Model Context Protocol.

Method A: Via the Claude UI (or ChatGPT UI)

If you are using the consumer-facing desktop or web applications, you can add the server directly through the UI settings.

For Claude Desktop/Web:

  1. Open Claude and navigate to Settings.
  2. Click on Integrations (or Connectors depending on your plan tier).
  3. Click Add MCP Server or Add custom connector.
  4. Paste the Truto MCP URL you generated earlier and click Add.

For ChatGPT (Enterprise/Pro):

  1. Go to Settings → Apps → Advanced settings.
  2. Enable Developer mode.
  3. Under MCP servers / Custom connectors, add a new server.
  4. Name it (e.g., "drchrono") and paste the Truto MCP URL.

Claude will immediately execute an initialize handshake and call tools/list to discover all available drchrono operations.

Method B: Via Manual Config File (Claude Desktop)

If you are developing locally with Claude Desktop, you can configure the MCP server using the claude_desktop_config.json file. Truto provides an SSE (Server-Sent Events) transport wrapper that makes remote URLs function seamlessly in local config files.

Open your Claude Desktop configuration file (typically located at ~/Library/Application Support/Claude/claude_desktop_config.json on macOS or %APPDATA%\Claude\claude_desktop_config.json on Windows) and add the following:

{
  "mcpServers": {
    "drchrono_prod": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-sse",
        "https://api.truto.one/mcp/f8e7d6c5b4a3..."
      ]
    }
  }
}

Restart Claude Desktop. The application will use npx to launch the SSE bridge, connecting your local Claude instance securely to the remote Truto-managed drchrono integration.

Hero Tools for drchrono

Truto automatically generates tools for every documented resource in the drchrono API. Below are 6 of the highest-leverage "hero" tools that enable advanced clinical and operational workflows.

list_all_drchrono_appointments

This tool retrieves and searches appointments and schedule breaks. It is the foundation for any pre-charting or daily schedule briefing workflow. You must provide one of since, occurred_since, date, or date_range.

"Fetch all of Dr. Smith's appointments for today (date: 2024-10-25) so we can review the patient list before morning rounds."

get_single_drchrono_patient_by_id

Retrieves the complete demographic and high-level medical record for a specific patient. Essential for enriching agent prompts with patient context before drafting clinical notes.

"Look up the patient record for ID 892341 and summarize their medication history consent status and date of first appointment."

create_a_drchrono_clinical_note_field_value

Creates a discrete clinical note entry tied to a specific appointment and a specific field template in drchrono. This is how LLM-generated summaries actually make it into the structured EHR chart.

"Create a clinical note field value for appointment ID 55432 and clinical_note_field ID 901. Set the value to: 'Patient reports mild headaches over the last 3 days, relieved by ibuprofen.'"

create_a_drchrono_lab_order

Generates a new lab order within drchrono so the physician can see it in their portal. This tool requires specific relational IDs for the patient, doctor, and the vendor sublab.

"Create a new lab order for patient ID 892341, ordered by doctor ID 443, using sublab ID 12. Add a note requesting a standard metabolic panel."

list_all_drchrono_lab_results

Searches and retrieves structured lab results. This allows Claude to analyze abnormal flags (is_abnormal), read LOINC codes, and parse observational descriptions to provide clinical summaries.

"Retrieve the recent lab results for patient ID 892341. Identify any records where the 'is_abnormal' flag is true and summarize the observation descriptions."

create_a_drchrono_task

Creates a task and assigns it to a clinical or administrative staff member. Useful for delegating follow-ups, billing checks, or pre-authorization requests directly from a Claude conversation.

"Create a task with the title 'Follow up on MRI authorization for John Doe'. Set the status to 'Open' and assign it to the front desk group."

For the complete inventory of available tools, query parameters, and schema definitions, visit the drchrono integration page.

Workflows in Action

Exposing individual endpoints to an LLM is useful, but the real power of MCP is enabling multi-step, autonomous workflows. Because Truto manages the flat input namespace and JSON schema mapping, Claude can cleanly chain drchrono tools together to accomplish complex operational tasks.

Workflow 1: Autonomous Pre-Charting and Note Injection

Persona: Clinical Practitioner / Medical Scribe

The Problem: Doctors spend hours reviewing past lab results and writing preliminary subjective notes before seeing a patient.

The Prompt:

"Review my appointments for today (2024-10-25). For the patient in my 10:00 AM slot, look up their recent lab results. Summarize any abnormal findings and create a new clinical note field value in today's appointment containing that summary for my review."

How Claude executes this:

  1. list_all_drchrono_appointments: Claude searches appointments where date is 2024-10-25. It finds the 10:00 AM slot, extracting appointment_id: 778899 and patient_id: 112233.
  2. list_all_drchrono_lab_results: Claude queries lab results for patient: 112233. It parses the JSON response, specifically looking at is_abnormal and observation_description.
  3. Internal Processing: Claude synthesizes the abnormal lab data into a concise medical summary.
  4. create_a_drchrono_clinical_note_field_value: Claude constructs a payload mapping the summary to the value property, attaching it to appointment: 778899 and a predefined clinical_note_field ID for the "Lab Review" section of the chart.
sequenceDiagram
    participant Claude as Claude
    participant MCP as Truto MCP Router
    participant API as drchrono API

    Claude->>MCP: Call list_all_drchrono_appointments (date=today)
    MCP->>API: GET /api/appointments?date=2024-10-25
    API-->>MCP: [Appointment 778899, Patient 112233]
    MCP-->>Claude: JSON Array

    Claude->>MCP: Call list_all_drchrono_lab_results (patient=112233)
    MCP->>API: GET /api/lab_results?patient=112233
    API-->>MCP: [Abnormal Lipid Panel Data]
    MCP-->>Claude: JSON Array

    Claude->>Claude: Synthesize clinical summary

    Claude->>MCP: Call create_a_drchrono_clinical_note_field_value
    MCP->>API: POST /api/clinical_note_field_values
    API-->>MCP: 201 Created (ID: 999111)
    MCP-->>Claude: Success Confirmation

Workflow 2: Post-Visit Lab Ordering and Task Delegation

Persona: Physician Assistant / Clinic Manager

The Problem: Ordering a lab and ensuring a Medical Assistant actually draws the blood requires context-switching between the EHR's lab module and the task management module.

The Prompt:

"I just finished with patient Sarah Jenkins (ID: 445566). Please create a lab order for her using our standard Quest Diagnostics sublab (ID: 8). Then, create an urgent task for the clinical team titled 'Draw blood for Sarah Jenkins CBC today'."

How Claude executes this:

  1. create_a_drchrono_lab_order: Claude formats the payload using the provided patient ID, the authed user's doctor ID, and the specific sublab ID, pushing it to drchrono.
  2. create_a_drchrono_task: Claude immediately calls the task tool, setting the title, setting status to a valid open string, and assigning it to the appropriate triage or clinical category.
graph TD
    A["User Prompt:<br>Order lab and create task"] --> B["Claude parses<br>IDs and intent"]
    B --> C["Call create_a_drchrono_lab_order<br>(patient, doctor, sublab)"]
    C --> D["drchrono API returns<br>New Lab Order ID"]
    D --> E["Call create_a_drchrono_task<br>(title, status, priority)"]
    E --> F["drchrono API returns<br>New Task ID"]
    F --> G["Claude responds:<br>Lab ordered, task assigned."]

Security and Access Control

When connecting an AI agent to a system containing Protected Health Information (PHI), least-privilege access is non-negotiable. Truto provides several architectural layers to secure your drchrono MCP server:

  • Method Filtering: You can restrict a server to specific operations. Setting methods: ["read"] ensures Claude can only execute get and list operations, physically preventing the model from altering patient charts or deleting records.
  • Tag Filtering: By passing tags: ["scheduling"] or tags: ["billing"], you can group tools and restrict the server to only expose endpoints relevant to the agent's specific role.
  • Secondary API Authentication: By setting require_api_token_auth: true, possession of the MCP URL is no longer enough to execute tools. The MCP client must also pass a valid Truto API token in the Authorization header, integrating the server into your standard identity stack.
  • Automatic Expiration: You can set an expires_at ISO datetime when creating the server. Once the TTL is reached, Cloudflare KV automatically evicts the token and a scheduled alarm permanently deletes the configuration from the database, leaving no stale access points.

Handling Rate Limits in Healthcare Automation

EHR APIs are notoriously sensitive to high request volumes, and aggressive LLM tool-calling can easily trigger rate limits (HTTP 429).

It is critical to understand how this is handled structurally: Truto does not retry, throttle, or apply backoff on rate limit errors. When the upstream drchrono API returns an HTTP 429, Truto passes that error directly back to the caller.

However, Truto does parse and normalize the upstream rate limit information into standardized headers (ratelimit-limit, ratelimit-remaining, ratelimit-reset) perfectly compliant with the IETF specification. The caller (your MCP client, LangChain framework, or custom agent loop) is entirely responsible for reading these headers and implementing the appropriate retry or exponential backoff logic.

Streamline Your Clinical Infrastructure

Connecting Claude to drchrono shouldn't require your engineering team to build a bespoke OAuth 2.0 reverse proxy, decipher complex EHR schemas, or write custom JSON-RPC protocol handlers. By utilizing a managed MCP architecture, you can derive AI-ready tools directly from the API documentation.

This approach reduces your integration maintenance burden to zero, allowing your team to focus on what actually matters: designing better clinical workflows, reducing administrative charting burden, and improving patient care outcomes through automation.

FAQ

How does Claude authenticate with the drchrono API?
Claude authenticates through a Model Context Protocol (MCP) server. Truto generates a secure, tokenized MCP URL tied to your authenticated drchrono integrated account. You simply provide this URL to Claude, abstracting away OAuth 2.0 token refreshes.
Can I restrict Claude to read-only access in drchrono?
Yes. When generating the MCP server in Truto, you can configure method filtering (e.g., `methods: ["read"]`). This ensures Claude only has access to GET and LIST endpoints, preventing the LLM from accidentally mutating patient data.
How do I handle drchrono rate limits with AI agents?
Truto passes upstream 429 rate limit errors directly to the caller and normalizes the rate limit headers (ratelimit-limit, ratelimit-remaining, ratelimit-reset) per the IETF spec. Your MCP client or agent framework is responsible for implementing retry and backoff logic.

More from our Blog