ClinGate

ClinGate

ClinGate is an MCP-native human-in-the-loop gateway that sits between AI agents and clinical tools, classifying every action by risk and forcing human approval before irreversible actions reach patient records.

Category
Visit Server

README

ClinGate

MCP Gateway for Clinical AI Agent Oversight

Python 3.11 License: Apache 2.0 Status: MVP FastAPI MCP

Why this exists

ClinGate is an open-source MCP (Model Context Protocol) gateway that sits between any AI agent framework and the clinical tools it calls. It classifies every action by risk in real time, and forces a human decision before anything irreversible reaches a patient record. Clinical AI agents are moving from answering questions to taking actions, but most multi-agent frameworks lack the built-in capability to enforce who is allowed to approve what, and how it gets logged. This is an infrastructure and dev-tool project, not a medical device. It acts as a governance layer any agent framework can sit behind, with clinical policy rules as the first shipped example.

Architecture Pipeline

graph TD
    Agent[Agent Orchestrator] -->|MCP Tool Calls| Gateway[ClinGate MCP Gateway Server]
    Gateway --> RuleEngine{Deterministic Rule Engine}
    RuleEngine -->|No match| LLM{LLM Risk Classifier}
    
    RuleEngine -->|Match| DecisionBranch
    LLM --> DecisionBranch
    
    DecisionBranch{Decision State} -->|AUTO_CLEAR| RealTool[Real Downstream Tool API]
    DecisionBranch -->|ESCALATE| Queue[Escalation Queue & Dashboard]
    DecisionBranch -->|BLOCK| Blocked[Blocked Action]
    
    Queue -->|Human Approves| RealTool
    Queue -->|Human Rejects| Blocked
    
    Queue -.->|Logs to| Ledger[(SQLite Audit Ledger)]
    DecisionBranch -.->|Logs to| Ledger

Request Lifecycle (order_medication)

sequenceDiagram
    participant A as Agent
    participant G as ClinGate Gateway
    participant F as openFDA API
    participant R as Rule Engine
    participant L as Audit Log
    
    A->>G: order_medication(drug="Adderall")
    G->>F: GET api.fda.gov/drug/label.json
    F-->>G: DEA Schedule II
    G->>R: Evaluate Policies (clinical-default.yaml)
    R-->>G: Match: block_controlled_substances -> BLOCK
    G->>L: Append row (BLOCK, reason: "Controlled substance")
    G-->>A: Call intercepted and held for review. Status: BLOCK.

Regulatory Grounding

This gateway directly addresses the human-oversight patterns expected by modern regulatory frameworks:

Requirement Article / Guidance How ClinGate addresses it
Human oversight capability EU AI Act Art. 14 Escalation queue with hard stop before execution
Record-keeping / logging EU AI Act Art. 12 Structured, exportable audit ledger per action
Deployer oversight assignment EU AI Act Art. 26 Reviewer role explicitly modeled, not implicit
Risk management system EU AI Act Art. 9 Configurable risk taxonomy + policy rules as first-class artifact
AI as Medical Device oversight UK MHRA guidance Same interception pattern maps directly to SaMD change-control expectations
Vendor oversight evidence NHS DTAC Dashboard + audit export is the artifact a DTAC assessor asks for

Real Data Sources

The single biggest thing that separates this from a toy demo is that the risk classification pipeline reasons over real, live, public data rather than a hard-coded drug list. Four public sources are wired in:

Source What it provides Endpoint (public, no key required for demo volume) Used for
openFDA Drug Label API Structured drug labeling including DEA schedule where present GET https://api.fda.gov/drug/label.json?search=openfda.generic_name:"{drug}"&limit=1 Real-time controlled-substance detection — replaces a static keyword list with an actual regulatory field lookup
RxNorm (NLM RxNav) Normalized drug names, RxCUI identifiers, ingredient relationships GET https://rxnav.nlm.nih.gov/REST/rxcui.json?name={drug} Normalizes whatever string the agent used ("tylenol" → acetaminophen RxCUI) before the rule engine matches it, so policy rules match on the real ingredient, not on string luck
ClinicalTrials.gov API v2 Live registry of recruiting trials by condition GET https://clinicaltrials.gov/api/v2/studies?query.term={condition}&pageSize=3 Grounds the create_referral action type with real, currently-recruiting trials instead of a fictional referral target
HAPI FHIR public R4 sandbox Real FHIR R4 Patient resources (synthetic patients, real schema and server) GET https://hapi.fhir.org/baseR4/Patient?_count=3&_format=json Populates the demo's patient context with genuine FHIR-shaped records, not a hand-typed JSON blob

Quickstart

  1. Clone the repository
git clone https://github.com/vilsee/clingate.git
cd clingate
  1. Setup Environment Variables
cp .env.example .env

(Note: CLASSIFIER_MODE=mock is the safe default requiring no Anthropic API key. If you have an Anthropic API key, set CLASSIFIER_MODE=live and supply your key).

  1. Run the application (While a Docker Compose configuration is provided, it has not yet been verified end-to-end. We recommend running locally with Uvicorn for development and testing.)
pip install -r requirements.txt
uvicorn backend.main:app --host 0.0.0.0 --port 8000 --reload

The FastAPI MCP server and the static Next.js/HTML dashboard will be available at http://localhost:8000.

Screenshots

  • TODO: ![Reviewer Queue](./docs/screenshots/queue_before.png) (The Reviewer Queue showing an ESCALATE item pending with a Classifier Disagreement badge)
  • TODO: ![Audit Export Ledger](./docs/screenshots/audit_export.png) (The raw JSON audit ledger showing the final_status and classifier_disagreement flags)
  • TODO: ![Live Pipeline Sandbox](./docs/screenshots/live_pipeline.png) (The demo.html page showing live API degradation)

Implemented vs Roadmap

As per the Product Requirements Document (PRD), the MVP milestone requires two differentiating features to be fully implemented, with the remaining four explicitly stubbed for the roadmap.

Implemented Features

1. Classifier Disagreement Signal

  • Status: Implemented
  • Description: Logs when the deterministic rule engine and the fallback LLM risk classifier would have made different decisions.
  • Implementation Details: Evaluated inside the interception loop (main.py). If the rule engine falls through, the LLM is queried. If the LLM returns an escalation or block (disagreeing with the implicit rule engine fall-through of AUTO_CLEAR), the classifier_disagreement boolean flag in the SQLite audit table is set to True.

2. SLA Breach Failsafe

  • Status: Implemented
  • Description: A background daemon that automatically transitions unreviewed ESCALATE items into BLOCK (or a specific SLA breach state) if human reviewers fail to act within a defined timeframe.
  • Implementation Details: Implemented as an asynchronous background task sla_breach_monitor in main.py. It loops every 60 seconds and updates any PENDING intercept call older than 5 minutes to SLA_BREACH_BLOCK in the database.

Roadmap Stubs (To Be Implemented)

These features have been explicitly documented as stubs in the backend/main.py source code to facilitate future roadmap development.

3. Clinical Trials Context Matching

  • Status: Stubbed (stub_feature_1_clinical_trials_matching)
  • Description: Would automatically query ClinicalTrials.gov and attach currently recruiting, localized trials to any blocked medication order to provide alternatives to the reviewer. (Note: ClinicalTrials.gov data is currently retrieved and attached for referrals as a baseline integration, but this advanced matching/suggestion algorithm is deferred).

4. FHIR Resource Validation

  • Status: Stubbed (stub_feature_2_fhir_resource_validation)
  • Description: Would validate outgoing tool arguments against active FHIR R4 profiles to ensure payload schema compliance before the call ever reaches the real system.

5. Reviewer Delegation Rules

  • Status: Stubbed (stub_feature_3_reviewer_delegation_rules)
  • Description: Would route specific ESCALATE items to specific specialist queues (e.g., Oncology-related referrals route only to boarded oncologists) rather than a global reviewer pool.

6. Agent Feedback Loop

  • Status: Stubbed (stub_feature_4_agent_feedback_loop)
  • Description: Would send natural language explanations of a BLOCK decision back to the autonomous agent, giving it the opportunity to self-correct and try a different tool call without human intervention.

Tech Stack

  • Gateway server: Python, FastAPI, MCP Python SDK
  • Rule engine: custom YAML DSL + pydantic validation
  • LLM classification: Anthropic API (Claude) via structured JSON output
  • Audit store: SQLite (migratable to PostgreSQL)
  • Dashboard: HTML/CSS/JS (vanilla stack matching a Next.js aesthetic)
  • External APIs: openFDA, RxNorm, ClinicalTrials.gov, HAPI FHIR

License & Contributing

Licensed under the Apache 2.0 License. Want to add your own YAML policy pack? See CONTRIBUTING.md.

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured