Skip to main content
Glama
Prithvi9x

mortgage-mcp

by Prithvi9x
README.md
# Mortgage MCP Server

An MCP (Model Context Protocol) server for mortgage loan processing, built
with the official Python MCP SDK (FastMCP). Modeled on how an enterprise
mortgage system is architected: an AI assistant only ever sees a small set
of high-level business tools, while all database access, third-party API
calls, and financial logic stay in an internal service layer.

## Exposed MCP Tools

Only these six tools are registered on the server — everything else is an
internal Python function that Claude/the LLM never sees directly:

| Tool | Purpose |
|---|---|
| `lookup_property(address)` | Retrieve full property info, geocoding on first lookup only |
| `analyze_locality(address)` | Nearby schools, hospitals, banks, transit, etc. in one response |
| `verify_documents(property_id)` | Check sale deed / owner ID / tax receipt exist |
| `schedule_site_visit(property_id, visit_date, officer_name)` | Create a site inspection |
| `evaluate_loan_application(customer_id, property_id, requested_amount)` | Full DTI/LTV/EMI/risk evaluation |
| `generate_final_report(application_id)` | Build the consolidated PDF mortgage report |

## Project Layout

```
mortgage_mcp/
├── server.py                 # MCP server entry point — wiring only
├── config.py                 # Loads .env, exposes typed settings
├── db.py                     # MySQL connection pool + query helpers
├── requirements.txt
├── .env.example
├── database/
│   └── schema.sql            # Normalized MySQL schema
├── services/                 # ALL business logic lives here (never MCP tools)
│   ├── customer_service.py
│   ├── property_service.py
│   ├── maps_service.py       # Google Geocoding / Places (New) / Routes
│   ├── document_service.py
│   ├── inspection_service.py
│   ├── loan_service.py
│   └── report_service.py
├── tools/
│   └── mortgage_tools.py     # The ONLY module defining MCP tools (thin)
├── documents/                # documents/property_<id>/{sale_deed,owner_id,tax_receipt}.pdf
├── inspections/               # inspection report text files
└── reports/                   # generated PDF mortgage reports
```

## Setup

1. **Install dependencies**

   ```bash
   pip install -r requirements.txt
   ```

2. **Create the database**

   ```bash
   mysql -u root -p < database/schema.sql
   ```

3. **Configure environment**

   ```bash
   cp .env.example .env
   # then edit .env with your DB credentials and Google Maps API key
   ```

   Your Google Cloud project needs the **Geocoding API**, **Places API
   (New)**, and **Routes API** enabled for the key in `GOOGLE_MAPS_API_KEY`.

4. **Seed sample data (optional)**

   Insert a customer and property manually via MySQL, or add a small
   seed script — `services/customer_service.insert_customer()` and
   `services/property_service.insert_property()` are ready to use for this.

5. **Run the server**

   ```bash
   python server.py
   ```

   Or, for local development with the MCP Inspector:

   ```bash
   mcp dev server.py
   ```

6. **Connect from Claude Desktop / another MCP client**

   Add an entry to your client's MCP config pointing at this server, e.g.
   for Claude Desktop's `claude_desktop_config.json`:

   ```json
   {
     "mcpServers": {
       "mortgage-mcp": {
         "command": "python",
         "args": ["/absolute/path/to/mortgage_mcp/server.py"]
       }
     }
   }
   ```

## Design Notes

- **Tools stay thin.** Every function in `tools/mortgage_tools.py` does
  input validation, calls one or more service functions, and returns a
  JSON-serializable dict. No SQL and no `requests` calls appear in that file.
- **Geocoding is cached.** `properties.latitude`/`longitude` are only
  populated once, on first `lookup_property`/`analyze_locality` call for
  an address; subsequent calls read straight from MySQL.
- **Document verification is a seam, not a dead end.** `document_service.py`
  currently only checks file existence, but `verify_sale_deed()`,
  `verify_owner_id()`, and `verify_tax_receipt()` are separate functions
  specifically so OCR or AI-based content verification can be dropped into
  each one independently later, without touching `verify_documents()`'s
  MCP interface.
- **Loan policy is configurable, not hard-coded.** Max LTV/DTI ratios,
  minimum credit score, and the base interest rate all come from
  `.env` via `config.LoanPolicyConfig`, so bank rules can be tuned without
  code changes.
- **Reports are self-contained.** `generate_final_report` recomputes the
  loan evaluation at report-build time (via `report_service.py`) so the
  PDF always reflects current data rather than a stale snapshot.

## Extending

- Add new MCP tools only in `tools/mortgage_tools.py`, keeping them thin.
- Add new business logic as functions inside the relevant `services/*.py`
  module (or a new service module) — never inline in the tool layer.
- New database tables/columns go in `database/schema.sql` plus a matching
  service module function; keep raw SQL out of `tools/` and out of
  `server.py`.