DEV Community

Beck_Moulton
Beck_Moulton

Posted on

Stop Manual Booking: Build a Claude 3.5 Doctor Appointment Assistant with MCP and Node.js

We’ve all been there: staring at a hospital's clunky registration portal at 7:59 AM, refreshing like a maniac, only to find that the specialist you need is fully booked. What if your AI could handle that for you?

With the release of Anthropic’s Model Context Protocol (MCP), the game has changed. We are moving away from hacky, one-off tool-calling implementations toward a standardized AI Agent architecture that allows models like Claude 3.5 Sonnet to seamlessly interact with local and remote resources. In this tutorial, we’re building a "Medical Appointment Agent" that doesn't just chat—it acts.

By leveraging Anthropic MCP, Node.js, and Playwright, we’ll create a system where Claude can check your calendar, find available slots on a medical portal, and resolve scheduling conflicts automatically.

Why MCP? The Missing Link in AI Automation

Before MCP, connecting an LLM to a specific database or a web scraper required building custom API wrappers every single time. Anthropic MCP provides a universal standard for Claude 3.5 automation, allowing us to expose "Tools" and "Resources" to the model with minimal friction.

For more production-ready examples and advanced patterns in agentic workflows, I highly recommend exploring the deep dives over at WellAlly Blog, which served as a major inspiration for this architecture.


The Architecture: How it Works

The flow involves Claude acting as the "Brain," the MCP Server acting as the "Hands," and Playwright acting as the "Eyes" to navigate the legacy hospital web UI.

graph TD
    User[User: 'Book an eye doctor for next Tuesday'] --> Claude[Claude 3.5 Sonnet]
    Claude -->|MCP Protocol| MCPServer[MCP Server - Node.js]
    subgraph "MCP Tools"
        MCPServer --> Tool1[Check Calendar]
        MCPServer --> Tool2[Search Hospital Portal]
        MCPServer --> Tool3[Submit Appointment]
    end
    Tool2 --> Playwright[Playwright Browser]
    Tool3 --> Playwright
    Playwright --> Hospital[Hospital Website]
    MCPServer -->|Success/Conflict| Claude
    Claude -->|Confirmation| User
Enter fullscreen mode Exit fullscreen mode

Prerequisites

To follow this advanced guide, you'll need:

  • Node.js v18+ installed.
  • An Anthropic API Key (or use the Claude Desktop App for testing).
  • Playwright for browser automation.
  • Basic familiarity with TypeScript.

Step 1: Initialize the MCP Server

First, let's set up our project and install the official MCP SDK.

mkdir medical-mcp-agent
cd medical-mcp-agent
npm init -y
npm install @modelcontextprotocol/sdk playwright zod
npx playwright install chromium
Enter fullscreen mode Exit fullscreen mode

We will use the @modelcontextprotocol/sdk to define our server. Create a file named server.ts.

Step 2: Defining the Appointment Tools

The core of our agent lies in the tools we expose to Claude. We need to define a schema that Claude understands.

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod";
import { chromium } from "playwright";

const server = new McpServer({
  name: "MedicalBookingHelper",
  version: "1.0.0",
});

// Tool 1: Search for available doctors
server.tool(
  "search_doctors",
  { department: z.string(), date: z.string() },
  async ({ department, date }) => {
    const browser = await chromium.launch({ headless: true });
    const page = await browser.newPage();

    // Logic to navigate to a medical portal
    await page.goto(`https://example-hospital.com/search?dept=${department}`);

    const slots = await page.evaluate(() => {
      // Scrape available time slots from the DOM
      return Array.from(document.querySelectorAll('.slot')).map(el => el.textContent);
    });

    await browser.close();
    return {
      content: [{ type: "text", text: `Available slots for ${department} on ${date}: ${slots.join(", ")}` }]
    };
  }
);

// Tool 2: Book the appointment
server.tool(
  "book_appointment",
  { doctorId: z.string(), slot: z.string(), patientName: z.string() },
  async ({ doctorId, slot, patientName }) => {
    // Playwright logic to fill out the form and submit
    // ... automation logic ...
    return {
      content: [{ type: "text", text: `Successfully booked Dr. ${doctorId} at ${slot} for ${patientName}.` }]
    };
  }
);
Enter fullscreen mode Exit fullscreen mode

Step 3: Handling Schedule Conflicts

One of the "Advanced" features of using Claude 3.5 Sonnet is its reasoning capability. You don't need to hard-code conflict resolution. If you provide a tool to get_calendar_events, Claude will:

  1. Call get_calendar_events.
  2. Call search_doctors.
  3. Compare the two lists in its context window.
  4. Only book a slot that is free in both.

This is the power of the Agentic Workflow!


Step 4: Connecting to Claude Desktop

To see this in action, add your server configuration to your claude_desktop_config.json:

{
  "mcpServers": {
    "medical_assistant": {
      "command": "node",
      "args": ["/path/to/your/medical-mcp-agent/build/server.js"]
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Once restarted, Claude will show a 🛠️ icon, indicating it can now access your medical booking tools.


The "Official" Way: Best Practices

While this tutorial gets you started, building production-grade agents requires handling rate limiting, session persistence, and multi-factor authentication (MFA) on medical portals.

For a deeper look into handling secure authentication in MCP or implementing human-in-the-loop patterns for sensitive medical actions, check out the specialized guides at WellAlly Tech Blog. They offer a wealth of knowledge on moving from "cool demo" to "production-ready AI system."


Conclusion

The Model Context Protocol is turning LLMs from isolated chatbots into powerful system orchestrators. By combining Claude 3.5's reasoning with Playwright's ability to touch the "real web," we've built a tool that saves time and reduces stress.

What's next for you?

  • Try adding a tool to send a WhatsApp confirmation once the booking is done.
  • Implement a "Waitlist Monitor" that polls for cancellations.

If you enjoyed this build, drop a comment below or share your own MCP tool ideas! Happy coding!

Top comments (0)