Fintech Data MCP Server
Fintech Data MCP Server
AI for Fintech | [MCP-001]
A template architecture for building an MCP server that gives any LLM structured access to your database. Point it at your tables, connect it to a client, and the model can query your data through well defined tools instead of guessing or hallucinating.
This is not a finished product. It is a starting point, built in layers so you can replace the database, the tables, and the tools without rewriting the server.
Architecture

The layers are independent by design:
DATA LAYER Generation, connection, schema mapping
ACCESS LAYER Repository queries, input and output schemas
MCP LAYER Tool definitions, server, demo clientSwapping SQLite for Postgres touches only the connection. Adding a table touches only the mapping, the repository and the schemas. Replacing MCP with another protocol touches only the tools and the server. Nothing cascades.
What This Solves
An LLM has no access to your internal data. You can paste records into a prompt, but that does not scale, goes stale immediately, and puts sensitive information into a context window with no control.
MCP solves this by letting the model call tools you define. The model decides when it needs data, calls the tool, and receives a structured response. You control exactly which queries exist and what they return.
This project implements that pattern for a common fintech scenario: looking up a customer across three separate systems (credit score, preapproved limit, and risk profile) and returning a consolidated view.
The synthetic data is here so you can run it immediately. The architecture is what you keep.
Deploy
Five steps from clone to a working LLM connection.
Step 1. Install
git clone https://github.com/junidepieri-design/mcp-001-fintech-data-server.git
cd mcp-001-fintech-data-server
py -3.13 -m venv venv
venv\Scripts\activate
pip install -r requirements.txtStep 2. Point at your database
Copy .env.example to .env and set the connection string.
DATABASE_URL=sqlite:///data/fintech.dbThe project uses SQLAlchemy, so any supported engine works with no code change:
postgresql://user:password@host:5432/database
mysql+pymysql://user:password@host:3306/database
mssql+pyodbc://user:password@host/database?driver=ODBC+Driver+17+for+SQL+ServerUse a read only database user. The server blocks write statements at the application layer, but a read only user at the database layer is the guarantee that actually matters.
Step 3. Map your schema
Open src/schema_mapping.py. This file declares which physical table and column corresponds to each logical field. It is the only place your database naming lives.
The default mapping assumes the synthetic tables:
'credit_score': {
'table': 'credit_score',
'primary_key': 'customer_id',
'columns': {
'customer_id': 'customer_id',
'score_value': 'score_value',
'score_band': 'score_band'
}
}Adapting to a real schema means changing the values on the right, never the keys on the left:
'credit_score': {
'table': 'TB_CLIENTE_SCORE',
'primary_key': 'COD_CLIENTE',
'columns': {
'customer_id': 'COD_CLIENTE',
'score_value': 'VLR_SCORE',
'score_band': 'FAIXA_SCORE'
}
}The queries, the schemas and the tools stay exactly the same. Only the mapping changes.
Step 4. Verify the data layer
Before wiring up any client, confirm the queries work.
If you are using the synthetic data, generate it first:
python -m src.data_generatorThen run the demo, which calls every tool directly without the MCP protocol:
python -m src.demoA successful run prints the health check, the three individual lookups, and the consolidated profile. If this fails, the problem is in the database or the mapping, not in the server.
Step 5. Connect the LLM
The server communicates over stdio. The client starts it as a subprocess, so there is no port to open and nothing to keep running.
For Claude Desktop, edit the configuration file:
Windows %APPDATA%\Claude\claude_desktop_config.json
macOS ~/Library/Application Support/Claude/claude_desktop_config.jsonAdd the server entry:
{
"mcpServers": {
"fintech-data": {
"command": "C:\\path\\to\\project\\venv\\Scripts\\python.exe",
"args": ["-m", "src.server"],
"cwd": "C:\\path\\to\\project"
}
}
}Point command at the Python inside your virtual environment, not the system Python, otherwise the dependencies will not be found.
Restart the client completely. The tools appear in the connectors menu, and the model can now answer questions like:
What is the credit profile of customer 10042?
Can customer 10042 receive a limit increase?
Compare the risk profile of customers 10042 and 10113.The model decides which tools to call and how to combine the results. You did not write any prompt logic to make that happen.
Connecting other clients
Any MCP compatible client works the same way. Cursor, Zed, and custom applications using the MCP Python SDK all launch the server over stdio with the same command. The configuration file location changes, the server does not.
Available Tools
Tool | Returns |
| Score value, band, model version, calculation date, top drivers |
| Approved amount, current limit, product, expiry, approval reason |
| Risk level, default probability, days past due, restrictions, review date |
| All three sources consolidated, with nulls where no record exists |
| Connection status and table availability |
Every tool takes a single customer_id and returns raw data. No business rules are applied, because every institution has its own.
Project Structure
mcp-001-fintech-data-server/
├── README.md
├── requirements.txt
├── .env.example
├── .gitignore
├── config/
│ ├── __init__.py
│ └── mcp_config.py
├── src/
│ ├── __init__.py
│ ├── data_generator.py
│ ├── database.py
│ ├── schema_mapping.py
│ ├── repository.py
│ ├── schemas.py
│ ├── server.py
│ └── demo.py
└── data/
└── fintech.dbKey Design Decisions
Predefined queries instead of text to SQL — The server exposes a fixed set of parameterized queries. The model chooses which one to call, never what SQL to run. Text to SQL against a production financial database is a risk no institution accepts, and it removes any guarantee about what the model can reach.
Raw data, no business logic — Tools return what the tables hold. Eligibility rules, risk thresholds and approval criteria differ at every institution, so embedding them here would make the template opinionated and less reusable. The model or the calling application applies the rules.
Read only enforced in two places — The application layer rejects any statement containing a write keyword, including chained statements. The database user should be read only as well. The first catches mistakes, the second catches everything else.
Schema mapping as a separate file — Table and column names live in one place. Adapting to a real database is a configuration change, not a refactor.
Row limit on every query — Results are capped, so a misconfigured client cannot pull the entire base into a context window.
Synthetic data generated, not committed — The generator produces internally consistent records: a low score drives a high default probability, which in turn blocks a limit increase. Running it produces a working database in seconds, and nothing sensitive lives in the repository.
Security Considerations
Before pointing this at anything real:
Create a dedicated read only database user
Never commit the .env file
Review which columns the mapping exposes
Confirm the row limit fits your use caseThe server runs locally over stdio, so there is no network exposure and no authentication layer. That is appropriate for a single analyst on their own machine. It is not appropriate for a shared environment.
What v2 Would Look Like
Running this for a team rather than a single user requires the transport to change from stdio to HTTP with SSE, which the protocol supports. That change brings everything a network service needs: authentication, per user authorization deciding who can see which fields, access logging for regulatory audit, rate limiting, and a deployment with monitoring.
The layered structure means those changes land in the tool and server layers only. The data and access layers stay as they are.
Author
Built by Odemir Depieri Jr — Data and AI specialist with 14 years of experience in data and AI within banks and financial institutions.
Part of the AI for Fintech applied research hub.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/junidepieri-design/mcp-001-fintech-data-server'
If you have feedback or need assistance with the MCP directory API, please join our Discord server