Skip to main content
Glama
leomengineer

clinic-mcp-server

by leomengineer

clinic-mcp-server

MCP Server: Company Data as Claude Tools.

Expose a clinic's knowledge base and structured records to Claude Desktop (or any MCP client) as callable tools — with the same grounding discipline as docs-rag-chatbot: read tools grounded with citations; write tools gated behind approval.

That contrast is the pitch. Anyone can wrap a search endpoint. Showing you thought about what happens when an agent can change something is what senior looks like.

Architecture

Claude Desktop (stdio MCP)
        │
        ▼
 clinic-mcp-server
   ├─ search_clinic_docs  → hybrid RRF over shared `chunks` (pgvector + tsvector)
   │                         + SIMILARITY_FLOOR gate → citations or "no relevant sources"
   ├─ get_patient_record  → Postgres `patients` (+ next confirmed appointment)
   ├─ list_appointments   → parameterized date-range query on `appointments`
   └─ create_appointment  → INSERT into `appointment_requests` (pending only)
                             NEVER writes confirmed `appointments`

Shares DATABASE_URL with docs-rag-chatbot (same Postgres). Retrieval code is local; the RAG chunks table is reused as-is. Clinic tables (patients, appointments, appointment_requests) are additive.

Related MCP server: vClinic MCP Server

Prerequisites

  1. Postgres/pgvector running for docs-rag-chatbot with docs ingested (make up && make ingest there).

  2. Python 3.12 + uv.

Quick start (two minutes)

cd clinic-mcp-server
uv sync
cp .env.example .env   # DATABASE_URL should match docs-rag-chatbot

# Create clinic tables + seed Jordan Lee et al. (does not touch chunks)
make setup

# Smoke-test over stdio (or point Claude Desktop at it — see below)
make serve

Claude Desktop config

Add this to your Claude Desktop claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/claude_desktop_config.json). Use absolute paths:

{
  "mcpServers": {
    "clinic": {
      "command": "/Users/leovet/.cargo/bin/uv",
      "args": [
        "run",
        "--directory",
        "/Users/leovet/freelance/clinic-mcp-server",
        "python",
        "-m",
        "clinic_mcp"
      ]
    }
  }
}

Restart Claude Desktop. You should see four tools under the clinic server.

A ready-to-merge example lives at claude_desktop_config.example.json.

Tip: find uv with which uv if your install path differs.

Demo (~60s)

  1. Open Claude Desktop with the MCP server connected — show the four tools.

  2. Ask: "Do you accept Delta Dental PPO?"
    → Claude calls search_clinic_docs, answers with a source citation (e.g. 06_insurance_faq.md).

  3. Ask: "when is Jordan Lee's next appointment?"
    → Claude calls get_patient_record with jordan-lee, returns structured data (insurance, upcoming crown consult).

  4. Ask: "book Jordan a crown consult next Tuesday"
    → Claude calls create_appointment; response is pending_approval — nothing committed to the confirmed calendar.

  5. Close: "Read tools answer. The write tool proposes and waits for a human."

Tools

Tool

Mode

Behavior

search_clinic_docs(query, top_k=5)

read

Hybrid retrieval; below SIMILARITY_FLOOR returns status=no_relevant_sources (empty chunks) — Claude must not invent.

get_patient_record(patient_id)

read

Patient row + next confirmed appointment. Missing patient / DB down → tool error (not empty success).

list_appointments(date_from, date_to)

read

Confirmed appointments in an inclusive date window (clinic TZ). Empty list is valid; DB failure is an error.

create_appointment(patient_id, datetime, service)

write (gated)

Inserts appointment_requests.status='pending' only. Returns pending_approval.

Demo patient id: jordan-lee.

Config (.env)

Variable

Purpose

Default

DATABASE_URL

Shared Postgres (same as RAG app)

postgresql://rag:rag@localhost:5432/rag

SIMILARITY_FLOOR

Dense cosine gate for doc search

0.35

CLINIC_TZ

Timezone for date windows / naive datetimes

America/Los_Angeles

Makefile

make sync     # uv sync --extra dev
make setup    # schema + seed
make schema   # clinic tables only
make seed     # demo patients / appointments
make serve    # stdio MCP server
make test     # pytest

Safety contract

  • Grounded reads: search_clinic_docs refuses weak matches instead of returning noise Claude could cite.

  • Loud failures: DB outages raise [db_unavailable] … tool errors. Empty appointment lists are only returned when the query succeeded.

  • Guarded writes: create_appointment never inserts into appointments. A human must approve the pending request before anything is confirmed.

  • Out of scope (intentionally): auth, multi-tenancy, OAuth, remote hosting, MCP resources/prompts. Four tools done well beats twelve half-wired.

Tests

make test

Covers tool discovery/schemas, Pydantic validation, retrieval gate + citations, structured errors, patient/appointment lookups, and the invariant that write calls create pending requests only.

Available Tools

4 tools
create_appointmentCreate appointment (pending approval)A

Propose a new appointment — does NOT confirm it.

Inserts a row into appointment_requests with status=pending and returns
pending_approval. A human must approve before anything lands on the
confirmed appointments calendar. Calling this twice creates two pending
requests; it never silently books.
ParametersJSON Schema
NameRequiredDescriptionDefault
serviceYesService to book, e.g. 'Crown consult'.
datetimeYesProposed start time (ISO-8601). Prefer timezone-aware values; naive values use the clinic timezone (America/Los_Angeles).
patient_idYesExisting patient id, e.g. 'jordan-lee'.

Output Schema

ParametersJSON Schema
NameRequiredDescription
statusNo
messageNo
requestYes

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description adds significant behavioral context beyond annotations: it inserts a row with status=pending, returns pending_approval, requires human approval, and never silently books. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is very concise, uses a short paragraph with a clear first sentence, and each sentence adds unique value. No unnecessary words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (3 required parameters, approval workflow), the description covers the behavior, return value, side effects, and constraints. The output schema is implied, and the description is sufficient for an AI agent to use correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has 100% description coverage with clear parameter descriptions. The tool description does not add further semantics for the parameters, so the baseline score of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb 'propose' and resource 'appointment', clearly distinguishing it from sibling tools like list_appointments which show confirmed ones. It states what it does (inserts a pending request) and what it does not do (confirm).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly says when to use it (to propose an appointment requiring approval) and notes that calling it twice creates two pending requests. It implies not for confirmed appointments but does not explicitly state when not to use or name alternatives like list_appointments for checking confirmed ones.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_patient_recordGet patient recordA
Read-only

Look up a patient by id: name, insurance, last visit, and next confirmed appointment.

Raises a tool error if the patient does not exist or the database is down —
never returns an empty success that could be mistaken for 'no appointments'.
ParametersJSON Schema
NameRequiredDescriptionDefault
patient_idYesStable patient id. Demo patient: 'jordan-lee'.

Output Schema

ParametersJSON Schema
NameRequiredDescription
statusNo
patientYes

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Adds error behavior (raises error if patient doesn't exist or DB down, never returns empty success) beyond annotations (readOnlyHint, destructiveHint). Provides useful safety context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with purpose, no fluff. Efficiently communicates what it does and key behavioral note.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple lookup tool with annotations and output schema, the description adds specific fields returned and error handling. Adequate for the complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% with a clear description including a demo value. Description adds no further parameter detail beyond schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Clearly states 'Look up a patient by id' and lists specific fields returned. Distinct from siblings: search_clinic_docs, list_appointments, create_appointment are different resources/actions.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Implies usage for retrieving patient info by ID, but no explicit when-to-use or when-not-to-use guidance. Does not mention alternatives despite sibling list being available.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_appointmentsList appointmentsA
Read-only

List confirmed appointments between date_from and date_to (inclusive).

date_to must be on or after date_from. Empty list with status=ok means no
confirmed appointments in that window — distinct from a database failure,
which raises a tool error.
ParametersJSON Schema
NameRequiredDescriptionDefault
date_toYesInclusive range end (YYYY-MM-DD), clinic local calendar.
date_fromYesInclusive range start (YYYY-MM-DD), clinic local calendar.

Output Schema

ParametersJSON Schema
NameRequiredDescription
countYes
statusNo
date_toYes
date_fromYes
appointmentsYes

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate a read-only, non-destructive tool. The description adds behavioral insight by clarifying that an empty list is distinct from a database error, which helps the agent interpret results correctly.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences front-load the core purpose and critical constraint. Every sentence adds value with no redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the output schema exists, the description adequately covers the behavior for edge cases (empty vs error). Parameter definitions are fully covered in the schema, and sibling tools are provided for context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% with descriptions for both parameters (inclusive range, clinic calendar). The description adds the constraint that date_to must be on or after date_from, but this is a minor addition beyond the schema definitions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Clearly states the tool lists confirmed appointments within a date range, with inclusive boundaries. Distinguishes from siblings like search_clinic_docs and get_patient_record by focusing on appointment listing.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly describes the scenario for use (listing confirmed appointments by date) and specifies that an empty list with status=ok indicates no appointments. However, it does not mention when not to use this tool or provide explicit alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_clinic_docsSearch clinic documentsA
Read-only

Hybrid-search the clinic knowledge base (pgvector + full-text, RRF-fused).

Returns cited chunks with source filename and scores when the best dense
similarity clears the SIMILARITY_FLOOR gate. Below that floor, returns
status=no_relevant_sources with an empty chunk list — do not fabricate
an answer from weak matches.
ParametersJSON Schema
NameRequiredDescriptionDefault
queryYesNatural-language question about BrightSmile policies, services, insurance networks, pricing, hours, booking rules, or care instructions.
top_kNoMax chunks to return when the relevance gate passes (default 5).

Output Schema

ParametersJSON Schema
NameRequiredDescription
queryYes
chunksNo
statusYes
messageNo
best_dense_scoreYes
similarity_floorYes

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark the tool as read-only and non-destructive. The description adds critical behavioral context: the similarity floor gate and the explicit instruction to not fabricate answers from weak matches. This goes beyond the annotation metadata.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two concise paragraphs. The first sentence immediately states the purpose and method. The second paragraph details return behavior and constraints. No extraneous information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has an output schema (as indicated by context signals), so return values are already documented. The description sufficiently covers the search behavior, the relevance gate, and the instruction against fabrication. It is complete for the tool's complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% for both parameters (query and top_k). The description adds no additional meaning beyond what the schema already provides. Baseline score of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool performs a 'hybrid-search' of the 'clinic knowledge base' with specific methods (pgvector + full-text, RRF-fused). This distinguishes it from sibling tools like get_patient_record, list_appointments, and create_appointment, which deal with patient data and scheduling.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explains that the tool returns cited chunks only when a similarity floor is met, and otherwise returns status=no_relevant_sources with an empty chunk list. It advises not to fabricate answers from weak matches. However, it does not explicitly state when to prefer this tool over siblings or provide when-not-to-use guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. 4 tool updatesv0.1.0
    • First observedcreate_appointment
    • First observedget_patient_record
    • First observedlist_appointments
    • First observedsearch_clinic_docs

TDQS

A4.3/5.0
Disambiguation5/5

Each tool addresses a distinct task: searching knowledge base, retrieving patient record, listing appointments, and creating appointment requests. No functional overlap exists.

Naming Consistency5/5

All tools follow a consistent verb_noun snake_case pattern (search_clinic_docs, get_patient_record, list_appointments, create_appointment).

Tool Count5/5

4 tools are well-scoped for a clinic management server, covering search, patient lookup, appointment listing, and appointment creation. Neither too few nor too many.

Completeness3/5

The set covers basic read and create operations, but lacks tools for updating patient records, confirming/cancelling appointments, or deleting requests, which are notable gaps for a full appointment management workflow.

Maintenance

ActivitySlowing
ResponsivenessSyncing

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables Claude Desktop to search custom knowledge bases using retrieval-augmented generation via a simple MCP tool.
    MIT
  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables AI agents to manage virtual clinic data including patients, visits, diagnoses, treatments, lab/radiology orders, and search medical literature and internal knowledge base.
    -
  • F
    license
    A
    quality
    C
    maintenance
    Enables Claude to query and manage home-care operations including clients, visits, and compliance, with schema-validated write tools and a tamper-evident audit log.
    5
    -

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/leomengineer/clinic-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server