CreddyMCP
by onatozmenn
README.md
---
title: Creddy
emoji: ๐
colorFrom: indigo
colorTo: blue
sdk: docker
app_port: 7860
pinned: false
---
<p align="center">
<img src="creedymcplogo.png" alt="Creddy logo" width="160" />
</p>
# Creddy
[](https://smithery.ai/server/onatozmen44/creddy-mcp)
[](https://github.com/onatozmenn/creddy-mcp)
[](LICENSE)
[](https://modelcontextprotocol.io)
[](https://www.python.org)
**A credit-risk analytics MCP server for Claude & ChatGPT.**
Ask questions in plain language โ it writes **safe, read-only SQL** over **30,000 real labeled
credit records**, scores **default risk** with an interpretable model, and pulls **live data
from Turkey's Central Bank (TCMB)** โ all over the Model Context Protocol.
> โ ๏ธ **Disclaimer:** This is an educational / portfolio project. The labeled data is the public
> UCI "Default of Credit Card Clients" dataset (Taiwan, 2005). It is **not** a real lending
> system and must not be used for actual credit decisions.
## ๐ฌ Example questions
Ask your assistant:
- *"What's the default rate by education level?"* โ `run_query`
- *"24 years old, credit limit 20k, 2-month delay in September โ will this client default?"* โ `predict_default`
- *"How good is the risk model (AUC, recall)?"* โ `model_metrics`
- *"Do clients with higher credit limits default less?"* โ `run_query`
- *"What are the current USD, EUR and gold prices?"* โ `tcmb_indicators` *(live TCMB)*
- *"Find TCMB series about credit-card spending."* โ `tcmb_search` *(live TCMB)*
- *"Which columns are in the data?"* โ `describe_schema`
Answers come from **real, labeled data** and an **actually trained model** โ not guesses.
## ๐ฅ Who is it for?
| Role | Start with | Why |
| --- | --- | --- |
| **Risk analyst** | `predict_default` ยท `model_metrics` | Score a borrower and see the signed drivers behind the decision |
| **Data scientist** | `run_query` ยท `describe_schema` | Explore 30k labeled records with safe SQL, no write risk |
| **BNPL / credit ops** | `tcmb_indicators` ยท `tcmb_search` | Live Turkish macro context (rates, FX, card spending) for underwriting |
## ๐งฐ Tools (9)
| Tool | What it does |
| --- | --- |
| `list_tables` | List database tables |
| `describe_schema` | Columns + types, to ground SQL generation |
| `run_query` | Validate + execute a read-only `SELECT` over `credit_clients` |
| `predict_default` | Predict a client's default probability + top risk factors |
| `model_metrics` | The trained model's AUC / precision / recall and key drivers |
| `tcmb_indicators` | **Live** headline Turkish indicators (USD, EUR, gold, rates, ...) โ no key |
| `tcmb_search` | Search the TCMB EVDS catalog for series by name (key-authenticated) |
| `tcmb_series` | A specific EVDS time series via the public REST API (key + current endpoint) |
| `example_questions` | Suggested questions |
## ๐ Connect it (no install)
The server is **live** (Hugging Face Spaces) โ most people need zero setup. Pick your client:
### ChatGPT
1. ChatGPT โ **Settings โ Connectors โ Advanced โ Developer mode** (enable).
2. **Add connector** and enter the MCP URL:
```
https://onatozmenn-creddy-mcp.hf.space/mcp
```
3. Save. Now ask *"What's the default rate by education level?"* in chat.
> Custom MCP tools only appear on accounts with **Developer mode** enabled.
### Claude Desktop
Add to `claude_desktop_config.json` (Windows: `%APPDATA%\Claude\claude_desktop_config.json` ยท
macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`):
```json
{
"mcpServers": {
"creddy": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://onatozmenn-creddy-mcp.hf.space/mcp"]
}
}
}
```
Restart Claude Desktop; the tools show up in the ๐จ menu. *(Requires Node.js for `npx`.)*
### Claude.ai (web)
On Pro / Max / Team (and Free โ one connector) you can connect a remote MCP directly:
1. **[Settings โ Connectors](https://claude.ai/settings/connectors)** โ **Add custom connector**.
2. Enter the MCP URL (leave OAuth fields empty โ the server needs no auth):
```
https://onatozmenn-creddy-mcp.hf.space/mcp
```
3. **Add**, then enable Creddy from the **"+" โ Connectors** menu in a chat.
### Smithery (one command)
```
npx -y @smithery/cli install onatozmen44/creddy-mcp --client claude
```
### VS Code / Cursor
VS Code โ `.vscode/mcp.json`:
```json
{ "servers": { "creddy": { "type": "http", "url": "https://onatozmenn-creddy-mcp.hf.space/mcp" } } }
```
Cursor โ `.cursor/mcp.json` (note the `mcpServers` key):
```json
{ "mcpServers": { "creddy": { "url": "https://onatozmenn-creddy-mcp.hf.space/mcp" } } }
```
## Architecture
```mermaid
flowchart LR
User([User]) -- "natural language" --> Client["Claude / ChatGPT / IDE"]
Client -- "MCP (stdio or HTTP)" --> Server["Creddy MCP server (FastMCP)"]
Server -- "run_query" --> Guard["SQL guard (sqlglot)"]
Guard --> DB[("Postgres (read-only)\nreal credit_clients")]
Server -- "predict_default / model_metrics" --> Model[["Risk model (scikit-learn)"]]
Server -- "tcmb_indicators / tcmb_search / tcmb_series" --> EVDS[["TCMB EVDS (live)"]]
DB --> Server
Model --> Server
EVDS --> Server
Server -- "results" --> Client --> User
```
Two independent safety layers protect the database: the **SQL guard** (`sqlglot` โ SELECT-only,
single statement, row cap) **and** a **read-only DB session**. Model-generated SQL is never
trusted blindly.
## Real data sources
| Source | What | Access |
| --- | --- | --- |
| **UCI Credit Default** | 30,000 real clients, real repayment history, **real default label** (~22%) | Free, no key ([UCI #350](https://archive.ics.uci.edu/dataset/350/default+of+credit+card+clients)) |
| **TCMB EVDS** | **Live** Turkish indicators: USD/EUR, gold, deposit & loan rates, reserves, M3, inflation | No key for indicators; free key for catalog search |
## Risk model
`creddy train-model` trains an **interpretable logistic-regression** pipeline (standardize
numerics + one-hot encode categoricals) on the real data with an 80/20 split. It reports
**AUC, accuracy, precision, recall, F1, KS**, picks the decision threshold with **Youden's J**,
and saves the model. Every `predict_default` returns the probability, a risk band, and the
**signed top factors** behind that specific decision โ explainable, adverse-action friendly.
Current hold-out performance: **AUC โ 0.71**, KS โ 0.37. A low-risk profile scores ~12% and a
high-risk profile ~58% (base rate โ 22%) โ meaningful scores, not just rankings.
---
## ๐ ๏ธ Run locally
Prerequisites: **Python 3.10+** and **Docker**.
```powershell
docker compose up -d # local Postgres
python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -e ".[dev]"
Copy-Item .env.example .env
creddy setup # schema + real data + trained model
creddy serve # stdio (or: creddy serve --http)
python eval/run_eval.py ; pytest # 12/12 eval, 24 tests
```
### CLI
```
creddy init-db | load-data [--limit N] | train-model | setup | serve [--http --host H --port P]
```
## โ๏ธ Self-host for free (Hugging Face + Neon)
1. **Managed Postgres:** create a free serverless DB on [Neon](https://neon.tech) or
[Supabase](https://supabase.com); note host / db / user / password.
2. **Hugging Face Space:** create a **Docker** Space and push this repo (it ships a
[`Dockerfile`](Dockerfile) + [`docker-entrypoint.sh`](docker-entrypoint.sh)). Add the DB as
Space **secrets**:
```
CREDDY_DB_HOST, CREDDY_DB_PORT, CREDDY_DB_NAME, CREDDY_DB_USER, CREDDY_DB_PASSWORD
CREDDY_DB_SSLMODE=require # Neon / Supabase require SSL
CREDDY_TCMB_API_KEY # optional
```
On first boot the container bootstraps (schema + data + model) and serves at
`https://<user>-<space>.hf.space/mcp`.
3. **Keep it awake (optional):** a GitHub Actions workflow
([`.github/workflows/keepalive.yml`](.github/workflows/keepalive.yml)) pings the server every
30 minutes โ set a repo secret `MCP_URL` to your `/mcp` URL.
## Data model (`credit_clients`)
Monetary columns are in **NT$**; `pay_*` are repayment-status codes per month
(`-1/0` = paid duly, `>=1` = months of delay); `defaulted` is the label.
```
client_id, credit_limit, sex, education, marriage, age,
pay_sep..pay_apr, -- repayment status (6 months)
bill_sep..bill_apr, -- bill statement amounts
pay_amt_sep..pay_amt_apr, -- amounts paid
defaulted -- TRUE = defaulted next month
```
## Project layout
```
sql/schema.sql # Postgres DDL
src/creddy/
config.py db.py sql_guard.py
data_loader.py # loads the real UCI dataset (ucimlrepo)
risk_model.py # trains + serves the default-risk model (scikit-learn)
tcmb.py # live TCMB EVDS client
server.py cli.py
eval/ # golden SQL + evaluation harness
tests/ # unit tests (no DB / no network required)
Dockerfile, docker-entrypoint.sh # container image for hosting
```
## Design decisions
- **Real, labeled data over synthetic** โ labels come from the source, so the risk story is genuine.
- **Interpretable model on purpose** โ signed per-decision factors (explainable scoring) over a marginally higher AUC.
- **Guard before LLM trust** โ AST inspection blocks DML/DDL, statement stacking and `COPY`/`SET`; the DB session is independently read-only.
- **Eval as a first-class artifact** โ `eval/` turns "does the SQL layer work?" into a measurable, CI-friendly pass rate.
## Security
- Read-only `SELECT` only, enforced at two layers (parser + DB session); per-query row cap.
- Secrets (DB password, TCMB key) come from the environment, never hard-coded.
- The UCI data is public and anonymized โ no real PII.
## Note on `tcmb_series`
TCMB migrated EVDS2 โ EVDS3. All three TCMB tools now target the EVDS3 service: `tcmb_indicators`
(no key) plus the key-authenticated `tcmb_search` and `tcmb_series`, which use the EVDS3
`igmevdsms-dis` REST endpoint. `tcmb_series` needs a valid `CREDDY_TCMB_API_KEY`; override
`CREDDY_TCMB_BASE_URL` only if the endpoint changes again.
## License
[MIT](LICENSE)
This server cannot be deployed
Maintenance
ActivityStale
ResponsivenessNo issues