GxP MDM MCP Server

GxP MDM MCP Server

Enables AI assistants to query and manage a GxP computerized system inventory as a knowledge graph, including blast-radius impact analysis, regulatory lineage, validation-gap detection, audit-trail-compliant status change approvals, and periodic review generation.

Category
Visit Server

README

GxP MDM MCP Server - Cypher Tools for Claude / ChatGPT / Cursor

This MCP server exposes your Computerized System Inventory as a Knowledge Graph via Cypher queries. Any Claude/ChatGPT agent can now query GxP master data without hallucinating.

Architecture

Claude / ChatGPT / Cursor
        |
        | MCP (stdio)
        v
  mcp_server.py (14 tools)
        |
        | Cypher queries
        v
  Neo4j (or MOCK mode: NetworkX + JSON) <- your MDM golden record

Why Cypher?

  • Blast radius is a graph traversal: MATCH (start)-[:SENDS_VIA*1..3]->(downstream) — impossible in SQL
  • Data lineage for ALCOA+ investigations
  • Regulation ground truth — agent can only cite clauses returned by Cypher, prevents hallucination

14 Tools Exposed

Tool Cypher What it does
cypher_query Custom Safe read-only Cypher for exploration
list_all_systems MATCH (s:ComputerizedSystem) RETURN Full inventory - auditors ask this first
get_system_details Full subgraph System + functions + e-records + supplier + interfaces
get_blast_radius MATCH (start)-[:SENDS_VIA*1..$depth]->(downstream) Killer app: What downstream GxP systems are impacted by change?
get_upstream_lineage Reverse traversal Where does data come from?
get_applicable_regulations (s)-[:HAS_FUNCTION]->(f)-[:REGULATED_BY]->(reg) Anti-hallucination: only these clauses can be cited
get_system_interfaces (s)-[flow:SENDS_VIA]->(target) API/file/manual interfaces with GxP flag
find_validation_gaps WHERE validation_status <> 'Validated' Non-validated GxP Direct systems
find_periodic_review_overdue WHERE next_review < date() Overdue periodic reviews
find_high_risk_functions WHERE is_gxp_critical AND risk=High E-sig, batch release, potency
get_supplier_risk (s)-[:SUPPLIED_BY]->(sup) Supplier audit status, SOC2
get_data_lineage MATCH (s)-[:GENERATES]->(e:ElectronicRecord) Lineage for a record type
get_gxp_inventory WHERE gxp_impact='Direct' GxP Direct inventory
assess_change_impact Composite Orchestrates 3 Cypher queries + generates impact assessment per GAMP 5 / CSA

Quick Start (No Neo4j needed - Mock Mode)

cd gxp_mdm_mcp_server
pip install -r requirements.txt

# Mock mode: uses JSON + NetworkX, no Neo4j required
python scripts/test_tools.py

# Should show:
# - List 4 systems
# - Veeva QMS details with downstream SAP
# - Blast radius: Veeva -> SAP
# - REJECT for audit trail purge
# - Minor for version upgrade

Mock mode is perfect for POC and Claude Desktop testing.

Prod Mode with Neo4j

# .env - set Neo4j creds
cp .env.example .env
# Edit .env with your Neo4j URI

# Start Neo4j
docker-compose up -d neo4j

# Load sample data + schema
python scripts/load_sample_data.py

# Test with Neo4j
python scripts/test_tools.py

# Start API harness (optional)
uvicorn src.api_server:app --reload --port 8000
# http://localhost:8000/cypher/list_all_systems
# http://localhost:8000/cypher/blast_radius?system_id=SYS-VEEVA-QMS-001

Claude Desktop Config

  1. Find your Claude config: ~/Library/Application Support/Claude/claude_desktop_config.json (Mac) or %APPDATA%/Claude/claude_desktop_config.json (Win)

  2. Add (use absolute path):

{
  "mcpServers": {
    "gxp-mdm-cypher": {
      "command": "python",
      "args": ["/absolute/path/to/gxp_mdm_mcp_server/src/mcp_server.py"],
      "env": {
        "NEO4J_URI": "",
        "NEO4J_USERNAME": "neo4j",
        "NEO4J_PASSWORD": "password"
      }
    }
  }
}

For mock mode, leave NEO4J_URI empty. For Neo4j, set to bolt://localhost:7687.

  1. Restart Claude Desktop. You should see 14 tools under 🔌.

  2. Try prompts:

List all GxP Direct systems in my inventory
> calls list_all_systems(gxp_impact="Direct")

What happens if I change Veeva QMS? Show blast radius
> calls get_blast_radius(system_id="SYS-VEEVA-QMS-001")

Assess this change: Enable audit trail purge after 7 years for Veeva QMS
> calls assess_change_impact -> should REJECT per 21CFR11.10(e)

Assess Veeva upgrade from 24R1 to 24R2 with no e-sig change
> calls assess_change_impact -> should be Minor per CSA low risk

Cursor Config

See config/cursor_config.json.example - add to .cursor/mcp.json

ChatGPT (with MCP support)

If using ChatGPT custom GPT with MCP, use config/chatgpt_mcp_config.json as reference. ChatGPT will call tools via stdio.

Cypher Queries - Ground Truth

All queries in src/cypher_tools.py. Key ones:

Blast radius (the moat):

MATCH (start:ComputerizedSystem {system_id: $system_id})
MATCH path = (start)-[:SENDS_VIA*1..$depth]->(downstream:ComputerizedSystem)
WHERE downstream.gxp_impact IN ['Direct', 'GxP Relevant']
RETURN downstream.system_id, length(path) as distance

Regulation anti-hallucination:

MATCH (s:ComputerizedSystem {system_id: $system_id})
OPTIONAL MATCH (s)-[:HAS_FUNCTION]->(f)-[:REGULATED_BY]->(reg)
RETURN collect(DISTINCT reg) as regulations

Agent must ONLY cite clause_ids returned here.

From POC to Production

  1. Replace data/*.json with real Veeva Vault API + ServiceNow CMDB + Okta
  2. Add write tools (with approval workflow) for updating validation_status
  3. Add vector search tool for regulation RAG (embed GAMP 5 2nd Ed)
  4. Add periodic review agent that calls find_periodic_review_overdue on schedule

You now own the layer every CSV agent must query.

Troubleshooting

  • No module named mcp: pip install mcp
  • Claude doesn't see tools: Check absolute path in config, restart Claude, check logs ~/Library/Logs/Claude/mcp*.log
  • Neo4j connection fails: Falls back to mock mode automatically - check NEO4J_URI

Good luck cornering the market.


NEW: Write Tools with Approval Workflow (GxP Compliant)

Why approval workflow?

21 CFR Part 11.50 and Annex 11 require:

  • 2-person rule (requester != approver)
  • Reason for change (ALCOA+ Complete)
  • Electronic signature manifestation (who, when, meaning)
  • Immutable audit trail (who, when, old/new, reason)

All write tools enforce this.

Write Tools Added

Tool What it does GxP Control
request_validation_status_change_tool Create pending change request Logs REQUEST audit, requires reason >=10 chars
approve_validation_status_change_tool Approve + apply change Enforces requester != approver, logs e-sig, updates system + next review date
reject_validation_status_change_tool Reject with reason Logs REJECT audit
list_pending_changes_tool List pending QA approvals
get_audit_trail_tool Full audit trail with e-signatures 21CFR11.10(e), Annex 11.7

Example Workflow via Claude

You: Change Veeva QMS status to Validated - Change Implemented, reason: IQ/OQ passed for 24R2 upgrade, requested by qa.john

Claude calls:
request_validation_status_change_tool(system_id="SYS-VEEVA-QMS-001", new_status="Validated - Change Implemented", reason="IQ/OQ passed for 24R2 upgrade, evidence in Veeva Vault VP-2024-089", requested_by="qa.john@company.com")

-> Returns request_id CHG-VAL-A1B2C3, status Pending Approval

You: Approve CHG-VAL-A1B2C3 by qa.sarah, comment: Reviewed IQ/OQ, approved

Claude calls:
approve_validation_status_change_tool(request_id="CHG-VAL-A1B2C3", approver="qa.sarah@company.com", approval_comment="Reviewed IQ/OQ")

-> Applies change, updates sample_systems.json, creates audit trail with e-signature

You: Show audit trail for Veeva QMS

Claude calls:
get_audit_trail_tool(system_id="SYS-VEEVA-QMS-001")
-> Returns who, when, old/new, reason, electronic signature manifestation

Try via API:

curl -X POST http://localhost:8000/request-status-change -H "Content-Type: application/json" -d '{"system_id":"SYS-VEEVA-QMS-001","new_status":"Validated - Change Implemented","reason":"IQ/OQ passed for 24R2 upgrade","requested_by":"qa.john@company.com"}'

curl -X POST http://localhost:8000/approve-status-change -d '{"request_id":"CHG-VAL-A1B2C3","approver":"qa.sarah@company.com","approval_comment":"Reviewed"}'

curl http://localhost:8000/audit-trail?system_id=SYS-VEEVA-QMS-001

NEW: Scheduled Periodic Review Agent

What it does

Automatically:

  1. Calls find_periodic_review_overdue Cypher daily at 8am (via APScheduler)
  2. For each overdue GxP Direct system, generates draft Periodic Review Report per GAMP 5 Section 6.5 and Annex 11.11
  3. Saves draft JSON + logs audit trail CREATE_DRAFT

Each draft includes 10 sections auditors expect:

  1. System description (from MDM)
  2. Changes since last review (from mock Jira)
  3. Deviations/incidents
  4. Audit trail review (sample, immutable check)
  5. User access review (dormant accounts)
  6. Backup/restore test
  7. Supplier review (SOC2)
  8. Data integrity ALCOA+
  9. Interfaces - blast radius from MDM graph
  10. Conclusion + required actions

Tools

Tool Purpose
run_periodic_review_scan Scan overdue (Cypher)
generate_periodic_review_drafts Scan + generate drafts for all overdue
generate_single_periodic_review Generate for one system
list_periodic_review_drafts List drafts

Run Scheduler

# Run once manually
python -c "from src.periodic_review_agent.agent import agent; print(agent.scan_overdue())"

# Generate drafts
python -c "from src.periodic_review_agent.agent import agent; print(agent.generate_drafts_for_overdue())"

# Run as daemon (daily 8am + every 6h demo)
python src/periodic_review_agent/scheduler.py

In prod, replace APScheduler with Airflow DAG or Temporal workflow that calls the MCP tool run_periodic_review_scan.

Via Claude

You: Run periodic review scan

Claude calls run_periodic_review_scan() -> finds 2 overdue systems

You: Generate drafts for overdue

Claude calls generate_periodic_review_drafts() -> creates PR-SYS-VEEVA-QMS-001-2025-XXXX reports

You: Show me draft for Veeva QMS
> Returns full 10-section report

Drafts saved to data/periodic_reviews/PR-*.json - ready to upload to Veeva Vault as ValidationArtifact.


This v2 makes you audit-ready: writes are controlled, audit trail is ALCOA+, and periodic reviews are automated — exactly what QA directors pay consultants $200/hr for.

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
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
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
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