Health Claims MCP Server
by immannan
README.md
# Healthcare MCP + A2A Server (Mock)
A sample project demonstrating the **Model Context Protocol (MCP)** and **Agent-to-Agent (A2A) communication** for the health insurance claims domain.
- **`mcp_server/`** — FastMCP server exposing 8 healthcare tools
- **`a2a/`** — Custom A2A protocol with 4 specialized agents that coordinate over JSON-RPC 2.0
- **`run_a2a.py`** — Standalone HTTP server that runs all agents together
All data is synthetic — no real PHI, no external calls.
> **Official A2A SDK**: The [`a2a-sdk`](https://pypi.org/project/a2a-sdk/) (v1.0.1+) is now the official Python library for the A2A protocol. This project contains a custom implementation built for training purposes.
---
## Project Structure
```
healthcare-mcp/
├── mcp_server/ # MCP server
│ ├── __init__.py
│ └── server.py # FastMCP with 8 healthcare tools
├── a2a/ # A2A protocol implementation
│ ├── __init__.py
│ ├── message.py # JSON-RPC 2.0 message types
│ ├── a2a_protocol.py # Protocol engine, registry, routing
│ └── agents.py # 4 healthcare domain agents
├── run_a2a.py # Standalone A2A HTTP server
├── test_a2a_communication.py # A2A protocol tests (40 tests)
├── diagrams/
│ ├── mcp.mmd # MCP Gateway architecture
│ └── a2a.mmd # A2A messaging pattern
├── requirements.txt
└── pytest.ini
```
---
## Setup
**Prerequisites:** Python 3.10+
```bash
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r requirements.txt
```
---
## Running the MCP Server
The MCP server exposes healthcare tools to any MCP-compatible client.
### stdio (default — for MCP clients)
```bash
python mcp_server/server.py
```
### Streamable HTTP
```bash
export MCP_TRANSPORT=streamable-http
export FASTMCP_HOST=127.0.0.1
export FASTMCP_PORT=8000
python mcp_server/server.py
```
Endpoint: `http://127.0.0.1:8000/mcp`
### SSE
```bash
export MCP_TRANSPORT=sse
python mcp_server/server.py
```
### MCP Environment Variables
| Variable | Default | Description |
|----------|---------|-------------|
| `MCP_TRANSPORT` | `stdio` | Transport: `stdio`, `streamable-http`, or `sse` |
| `FASTMCP_HOST` | `127.0.0.1` | Bind host for HTTP transports |
| `FASTMCP_PORT` | `8000` | Bind port for HTTP transports |
| `FASTMCP_STREAMABLE_HTTP_PATH` | `/mcp` | URL path for streamable-http endpoint |
| `MCP_MOUNT_PATH` | _(none)_ | Optional mount path prefix |
---
## Running the A2A Server
The A2A server starts all four healthcare agents and exposes them over HTTP. It uses a local MCP client that calls the MCP tool functions in-process — no separate MCP server required.
```bash
python run_a2a.py
```
The server starts on `http://127.0.0.1:8001` by default.
### A2A Environment Variables
| Variable | Default | Description |
|----------|---------|-------------|
| `A2A_HOST` | `127.0.0.1` | Bind host |
| `A2A_PORT` | `8001` | Bind port |
### A2A Endpoints
| Method | Path | Description |
|--------|------|-------------|
| `GET` | `/.well-known/agent.json` | Agent card — capabilities and metadata for discovery |
| `GET` | `/agents` | List all registered agents |
| `POST` | `/` | Receive an A2A JSON-RPC 2.0 message |
### Example: Discover agents
```bash
curl http://127.0.0.1:8001/.well-known/agent.json | python -m json.tool
```
### Example: Send an A2A message
```bash
curl -s -X POST http://127.0.0.1:8001/ \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "check_member_eligibility",
"params": {"member_id": "M-1001"},
"id": "req-001",
"sender": "external-client",
"recipient": "claims-agent",
"type": "request"
}' | python -m json.tool
```
---
## MCP Tools
### Claims
| Tool | Parameters | Description |
|------|-----------|-------------|
| `list_member_claims` | `member_id`, `status?` | List claims, optionally filtered by `paid`/`pending`/`denied` |
| `get_claim_detail` | `claim_id` | Full claim with member, provider, and adjudication amounts |
| `submit_claim_inquiry` | `claim_id`, `inquiry_type`, `note` | Submit an inquiry ticket |
### Benefits
| Tool | Parameters | Description |
|------|-----------|-------------|
| `get_member_benefits` | `member_id` | Deductible and OOP balances for the member's plan |
| `estimate_member_responsibility` | `member_id`, `procedure_code`, `billed_amount`, `network?` | Cost-sharing estimate |
### Providers & Authorizations
| Tool | Parameters | Description |
|------|-----------|-------------|
| `search_providers` | `specialty`, `zip_code?`, `network?` | Search providers by specialty |
| `create_prior_authorization` | `member_id`, `provider_id`, `procedure_codes`, `service_date`, `diagnosis_codes?` | Submit prior auth request |
| `get_prior_authorization_status` | `auth_id` | Fetch current status of a prior auth |
---
## A2A Agent System
### Agents
| Agent | ID | Role |
|-------|----|------|
| `MemberAssistAgent` | `member-assist-agent` | Patient coordinator — checks eligibility, finds providers |
| `ClaimsAgent` | `claims-agent` | Claims processor — eligibility, claim history, cost estimates |
| `ProviderAdvocateAgent` | `provider-advocate-agent` | Network manager — provider search |
| `BenefitsAgent` | `benefits-agent` | Benefits specialist — cost calculations |
### Communication Flow
```
MemberAssistAgent
├─ A2A → ClaimsAgent: "check_member_eligibility"
│ ├─ MCP: list_member_claims, get_member_benefits
│ └─ MCP: get_claim_detail
│
└─ A2A → ProviderAdvocateAgent: "search_network_providers"
└─ MCP: search_providers
ClaimsAgent
└─ A2A → BenefitsAgent: "calculate_member_responsibility"
└─ MCP: estimate_member_responsibility
```
### Using agents in code
```python
import asyncio
from a2a import A2AProtocol, MemberAssistAgent, ClaimsAgent, ProviderAdvocateAgent, BenefitsAgent
async def main():
protocol = A2AProtocol()
member_assist = MemberAssistAgent(protocol, mcp_client)
claims = ClaimsAgent(protocol, mcp_client)
provider_advocate = ProviderAdvocateAgent(protocol, mcp_client)
benefits = BenefitsAgent(protocol, mcp_client)
for agent in [member_assist, claims, provider_advocate, benefits]:
await agent.register()
protocol.register_handler("check_member_eligibility", claims.handle_check_member_eligibility)
protocol.register_handler("search_network_providers", provider_advocate.handle_search_network_providers)
protocol.register_handler("calculate_member_responsibility", benefits.handle_calculate_member_responsibility)
eligibility = await member_assist.check_eligibility("M-1001")
providers = await member_assist.find_providers("primary care", "55401")
asyncio.run(main())
```
---
## Tests
```bash
pytest -v # all 40 tests
pytest test_a2a_communication.py # A2A protocol tests only
```
See [TEST_GUIDE.md](TEST_GUIDE.md) for test documentation and [QUICKSTART.md](QUICKSTART.md) for filtering commands.
---
## Mock Data Reference
### Members
| ID | Name | Plan |
|----|------|------|
| `M-1001` | Jordan Lee | `P-100` Optum Choice PPO |
| `M-1002` | Casey Patel | `P-200` Optum Select HMO |
### Plans
| ID | Name | Deductible | Remaining | OOP Max | Remaining | In-network Coinsurance |
|----|------|-----------|-----------|---------|-----------|------------------------|
| `P-100` | Optum Choice PPO | $1,500 | $420 | $5,000 | $2,100 | 20% |
| `P-200` | Optum Select HMO | $500 | $120 | $3,000 | $980 | 10% |
### Providers
| ID | Name | Specialty | Network | ZIP |
|----|------|-----------|---------|-----|
| `PR-2001` | Northside Primary Care | primary care | in-network | 55401 |
| `PR-2002` | Lakeview Ortho Clinic | orthopedics | in-network | 55111 |
| `PR-2003` | Metro Imaging Center | radiology | out-of-network | 55415 |
### Claims
| ID | Member | Provider | Status | Billed |
|----|--------|----------|--------|--------|
| `C-10001` | M-1001 | PR-2001 | paid | $250.00 |
| `C-10002` | M-1001 | PR-2003 | pending | $980.00 |
| `C-10003` | M-1002 | PR-2002 | denied (prior auth required) | $1,350.00 |
### Prior Authorizations
| ID | Member | Status |
|----|--------|--------|
| `PA-9001` | M-1002 | approved |
---
## Architecture Diagrams
| File | Description |
|------|-------------|
| [diagrams/mcp.mmd](diagrams/mcp.mmd) | MCP Gateway routing to domain servers |
| [diagrams/a2a.mmd](diagrams/a2a.mmd) | A2A messaging between agents |
Render with [Mermaid Live Editor](https://mermaid.live) or any Mermaid-compatible viewer.
---
## MCP Inspector
[MCP Inspector](https://github.com/modelcontextprotocol/inspector) is a browser-based tool for calling MCP tools interactively.
```bash
npm install
npm start
```
---
## Notes
- All data is in-memory and resets on restart.
- `estimate_member_responsibility` uses mock multipliers (75% in-network, 60% out-of-network). Not a guarantee of payment.
- No PHI, no external API calls, no persistent storage.
- The official A2A Python SDK is [`a2a-sdk>=1.0.1`](https://pypi.org/project/a2a-sdk/). The `a2a/` module in this project is a custom educational implementation of the same protocol patterns.
This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues