A production-grade multi-agent credit decisioning platform built with MCP (Model Context Protocol), A2A (Agent-to-Agent) communication, Strands Agents SDK, and AWS Bedrock.
┌──────────────────────────────┐
│ React Dashboard │
│ (Port 3000 / Nginx) │
└──────────────┬───────────────┘
│ REST API
┌──────────────▼───────────────┐
│ FastAPI Backend │
│ (Port 8000) │
└──────────────┬───────────────┘
│
┌────────────────────────▼─────────────────────────┐
│ Orchestrator Agent │
│ (Coordinates full pipeline) │
└──┬──────────┬──────────┬──────────┬─────────────┘
│ A2A │ A2A │ A2A │ A2A
┌──────▼──┐ ┌────▼─────┐ ┌──▼──────┐ ┌─▼──────────┐
│ Document │ │Financial │ │ Risk │ │ Decision │
│ Agent │ │ Agent │ │ Agent │ │ Agent │
│ │ │ │ │ │ │ │
│ Extract │ │ Compute │ │ Score │ │ Apply │
│ financ- │ │ DSCR, │ │ credit, │ │ credit │
│ ials from│ │ leverage,│ │ finan- │ │ policy, │
│ docs │ │ current │ │ cial, │ │ generate │
│ │ │ ratio, │ │ collat- │ │ recommen- │
│ │ │ EBITDA │ │ eral, │ │ dation │
└──────────┘ └──────────┘ │ market │ └────────────┘
└─────────┘
┌──────────────────────────────────────────────────────┐
│ MCP Server (Port 8001) │
│ Tools: extract_financials, calculate_ratios, │
│ score_risk, apply_policy, + 4 more │
└──────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────┐
│ Redis (Port 6379) │
│ Task state & result storage │
└──────────────────────────────────────────────────────┘
HTTP POST /api/v1/credit/evaluate
└── OrchestratorAgent
├── A2A → DocumentAgent (extract financials from docs)
├── A2A → FinancialAgent (compute DSCR, leverage, ratios)
├── A2A → RiskAgent (score risk across 4 dimensions)
└── A2A → DecisionAgent (apply policy → APPROVE/DECLINE/REFER)
└── CreditDecision → stored in Redis → returned via API
- Docker and Docker Compose
- Git
git clone git@github.com:GanB/mcp-a2a-demo.git
cd mcp-a2a-demo
cp .env.example .env
docker-compose up --buildOpen http://localhost:3000 to access the dashboard.
# Backend
pip install -r requirements.txt
MOCK_AWS=true uvicorn api.main:app --port 8000
# NOTE: --reload is for development only; never use it in production
# MCP Server (separate terminal)
MOCK_AWS=true uvicorn mcp_server.server:app --port 8001
# Frontend (separate terminal)
cd frontend && npm install && npm run devpip install pytest pytest-asyncio httpx slowapi
MOCK_AWS=true python -m pytest tests/ -vAll agents work without real AWS credentials when MOCK_AWS=true (the default):
| Agent | Mock Behavior |
|---|---|
| DocumentAgent | Returns fixture financial data (revenue=$5M, assets=$8M) |
| FinancialAgent | Computes real ratios from mock financial data |
| RiskAgent | Returns configurable risk scores using weighted model |
| DecisionAgent | Applies real policy rules against mock scores |
This allows a full end-to-end demo with no cloud costs or credentials.
| Variable | Default | Description |
|---|---|---|
AWS_REGION |
us-east-1 |
AWS region for Bedrock |
AWS_ACCESS_KEY_ID |
(empty) | AWS access key |
AWS_SECRET_ACCESS_KEY |
(empty) | AWS secret key |
BEDROCK_MODEL_ID |
anthropic.claude-3-5-sonnet-20241022-v2:0 |
Bedrock model ID |
MCP_SERVER_URL |
http://mcp:8001 |
MCP server endpoint |
REDIS_URL |
redis://:changeme@redis:6379 |
Redis connection URL (with password) |
REDIS_PASSWORD |
changeme |
Redis authentication password |
API_SECRET_KEY |
(empty) | API key for X-API-Key header auth. When empty, auth is disabled (dev mode). Set a strong secret in production. |
MOCK_AWS |
true |
Set false to use real Bedrock |
CORS_ORIGINS |
http://localhost:3000 |
Comma-separated allowed CORS origins |
RATE_LIMIT |
60/minute |
Default rate limit per IP |
LOG_LEVEL |
INFO |
Logging level (DEBUG, INFO, WARNING, ERROR) |
MAX_UPLOAD_BYTES |
10485760 |
Maximum file upload size in bytes (default 10 MB) |
This platform includes the following security measures:
- API Key Authentication — All protected endpoints require an
X-API-Keyheader whenAPI_SECRET_KEYis configured. When unset, auth is disabled for easy local development. - CORS Restrictions — Only origins listed in
CORS_ORIGINSare allowed (default:http://localhost:3000). Methods restricted to GET and POST. - Rate Limiting — All endpoints enforce per-IP rate limits (configurable via
RATE_LIMIT). - Security Headers — Every response includes
X-Frame-Options: DENY,X-Content-Type-Options: nosniff,X-XSS-Protection,Referrer-Policy, andPermissions-Policy. - Error Sanitization — Internal exception details are never exposed to clients; generic error messages are returned.
- File Upload Validation — Enforces file size limit (10 MB default), content type whitelist (PDF/JSON only), file extension validation, and filename sanitization.
- MCP Tool Argument Validation — Tool arguments are validated against handler signatures; unknown parameters are rejected.
- Redis Authentication — Redis requires a password (
REDIS_PASSWORD). - Docker Non-Root — All containers run as non-root users.
- SSRF Protection — MCP proxy only allows requests to known internal hostnames.
- Audit Logging — Credit evaluations, report access, and document uploads are logged with client IP and action type.
- Set a strong
API_SECRET_KEY(e.g.,openssl rand -hex 32) - Set a strong
REDIS_PASSWORD - Configure
CORS_ORIGINSto your actual frontend domain - Set
LOG_LEVEL=WARNINGto reduce log verbosity - Place behind a reverse proxy with TLS termination and add
Strict-Transport-Securityheader - Set
MOCK_AWS=falseand configure real AWS credentials
- Receives credit application payload
- Spawns and coordinates child agents via A2A protocol
- Aggregates results into final evaluation report
- Tools:
route_to_agent,aggregate_results
- Accepts PDF or structured JSON financial docs
- Extracts income statements, balance sheets, cash flows
- Uses AWS Textract in production, mock data in demo mode
- MCP Tool:
extract_financials
- Receives FinancialData from DocumentAgent via A2A
- Computes DSCR, leverage ratio, current ratio, EBITDA margin
- Tools:
calculate_ratios,benchmark_against_industry
- Receives RatioAnalysis + borrower profile
- Scores risk across: credit history, financials, collateral, market
- Uses weighted scoring model with configurable weights
- Tool:
score_risk_factors
- Receives RiskScore + policy rules
- Applies credit policy: min score, max LTV, DSCR floor
- Generates recommendation with rationale and conditions
- Tool:
apply_credit_policy
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/v1/credit/evaluate |
Submit credit application for evaluation |
GET |
/api/v1/credit/{task_id} |
Poll evaluation status |
GET |
/api/v1/credit/{task_id}/report |
Get full credit report |
POST |
/api/v1/documents/upload |
Upload financial documents |
GET |
/api/v1/agents/status |
Health status of all agents |
GET |
/api/v1/tools |
List all MCP tools |
GET |
/health |
API health check |
curl -X POST http://localhost:8000/api/v1/credit/evaluate \
-H "Content-Type: application/json" \
-d '{
"borrower_name": "Acme Corp",
"loan_amount": 500000,
"loan_purpose": "Working capital",
"collateral_value": 750000,
"industry_code": "5411",
"years_in_business": 8,
"credit_history_score": 720,
"annual_revenue": 5000000
}'Response:
{
"task_id": "a1b2c3d4e5f6",
"status": "PENDING",
"message": "Credit evaluation started. Poll /credit/{task_id} for status."
}curl http://localhost:8000/api/v1/credit/a1b2c3d4e5f6/reportThe MCP server (port 8001) exposes 8 tools discoverable via GET /tools:
| Tool | Description |
|---|---|
extract_financials |
Extract structured financial data from documents |
parse_pdf |
Parse base64-encoded PDF content |
calculate_ratios |
Compute DSCR, leverage, current ratio, EBITDA margin |
get_benchmarks |
Get industry benchmark ratios by NAICS code |
score_risk |
Compute composite risk score with breakdown |
get_policy_rules |
Retrieve credit policy thresholds and weights |
apply_policy |
Apply credit policy for APPROVE/DECLINE/REFER decision |
format_recommendation |
Generate human-readable credit report |
| Service | Port | Description |
|---|---|---|
api |
8000 (exposed) | FastAPI backend |
mcp |
8001 (internal only) | MCP protocol server |
frontend |
3000 (exposed) | React dashboard (Nginx) |
redis |
6379 (internal only) | Password-protected task storage |
All services include health checks, auto-restart, and run as non-root users. Redis and MCP are not exposed to the host network.
mcp-a2a-demo/
├── agents/
│ ├── orchestrator/ # Master orchestrator agent
│ ├── document_agent/ # PDF/document ingestion & extraction
│ ├── financial_agent/ # Financial statement analysis
│ ├── risk_agent/ # Risk scoring & credit rating
│ ├── decision_agent/ # Final credit recommendation
│ └── startup.py # Agent registration
├── api/ # FastAPI backend
│ ├── main.py
│ ├── store.py # Redis/in-memory task storage
│ ├── routers/
│ │ ├── credit.py # Credit evaluation endpoints
│ │ ├── documents.py # Document upload endpoint
│ │ └── agents.py # Agent status & tools proxy
│ └── models/
│ └── requests.py # Request/response models
├── frontend/ # React + TypeScript dashboard
│ ├── src/
│ │ ├── components/
│ │ │ ├── CreditApplicationForm.tsx
│ │ │ ├── AgentPipelineView.tsx
│ │ │ ├── RiskScoreDashboard.tsx
│ │ │ ├── CreditDecisionReport.tsx
│ │ │ └── AgentStatusPanel.tsx
│ │ ├── api/client.ts
│ │ └── App.tsx
│ └── Dockerfile
├── mcp_server/ # MCP protocol server
│ ├── server.py
│ ├── tools/
│ │ ├── document_tools.py
│ │ ├── financial_tools.py
│ │ ├── risk_tools.py
│ │ └── decision_tools.py
│ └── schemas/
│ └── models.py
├── a2a/ # Agent-to-Agent communication
│ ├── protocol.py # A2A message envelope
│ ├── router.py # Message routing
│ ├── registry.py # Agent registry
│ └── message_queue.py # Async message queue
├── shared/ # Shared schemas & config
│ ├── schemas.py
│ └── config.py
├── tests/
├── docker-compose.yml
├── Dockerfile.api
├── Dockerfile.mcp
├── requirements.txt
├── .env.example
└── README.md
MIT