Skip to main content
Glama
sinan-ozel

MCP Server Template

by sinan-ozel

CI/CD Docker Hub Docker Pulls Finance Tools License

finance-tools

An MCP (Model Context Protocol) server exposing financial calculation tools — loan rates and payments, investment projections, IRR, and bond yields. Built with FastMCP, runs via Docker, and connects to any MCP client that supports HTTP transport (Claude Desktop, Claude.ai, Cursor, etc.).

Full documentation: https://sinan-ozel.github.io/finance-tools/

Quickstart

docker run -p 8000:8000 sinan-ozel/finance-tools:latest

The MCP endpoint is at:

http://localhost:8000/mcp

The server uses Streamable HTTP transport (the current MCP standard).


Related MCP server: MY MCP

Tools

Tool

What it does

annualized_interest_rate

Solves for the implied rate of a fixed-payment loan; returns monthly rate, effective annual rate, and APR

monthly_payment

The inverse: fixed monthly payment for a principal, rate, and term, plus total paid and total interest

loan_payoff_months

How long a balance takes to retire at a fixed payment; flags payments that don't cover monthly interest

future_value

Projects investment growth from a principal and optional monthly contributions, separating contributions from interest earned

internal_rate_of_return

IRR of a cash-flow series (NPV = 0), with the periodic rate annualized at a configurable frequency

bond_yield_to_maturity

Solves for YTM and current yield of a fixed-coupon bond; supports any compounding frequency

All rates are expressed in percent (e.g. 12 for 12%). Loan and investment tools use effective annual rates consistently, so outputs from one tool can be fed into another. See the documentation site for full input/output schemas and examples.


Development

The only requirement is Docker — every dev operation runs through Docker Compose.

Run the tests

docker compose -f tests/docker-compose.yaml up --build --abort-on-container-exit --exit-code-from test

This starts the MCP server, waits for it to be healthy, then runs pytest against it with pytest-mcp-tools.

Lint

docker compose -f lint/docker-compose.yaml up --build --abort-on-container-exit

Reformat

docker compose -f reformat/docker-compose.yaml up --build --abort-on-container-exit

Reformatting runs black, docformatter, and isort on server/ and tests/, then writes changes back to disk (via volume mount). On non-main branches CI commits these changes automatically.

Validate docs

docker compose -f docs-validate/docker-compose.yaml up --build --abort-on-container-exit

Run the MCP Inspector

docker compose -f inspector/docker-compose.yaml up --build

Then open the URL printed in the logs (includes the auth token):

http://localhost:6274/?MCP_PROXY_AUTH_TOKEN=<token>

VS Code Tasks

Open Terminal → Run Task (or Ctrl+Shift+P → Tasks: Run Task):

Task

What it does

test

Runs the full test suite (server + test runner containers)

lint

Runs ruff against server/ and tests/

reformat

Formats code with black + docformatter + isort

validate-docs

Builds MkDocs site with --strict

inspector

Starts the server + MCP Inspector (leaves running in background)


CI/CD Pipeline

The workflow at .github/workflows/ci.yaml runs on every push and pull request:

push (any branch)
│
├── reformat        ← runs black/isort/docformatter
│   └── (commits reformatted code back, non-main branches only)
│
├── lint            ← ruff check (needs: reformat)
├── test            ← pytest --mcp-tools (needs: reformat)
├── validate-docs   ← mkdocs build --strict
└── detect-changes  ← checks if server/ or README changed
    │
    └── publish (main only, when changed)
        ├── Build & push Docker image to Docker Hub
        │   ├── stable:  sinan-ozel/finance-tools:1.2.3  +  :latest
        │   └── dev:     sinan-ozel/finance-tools:1.2.4.dev202401011200
        ├── Tag stable release in git
        ├── Create GitHub Release
        └── publish-docs (stable + docs exist)
            └── mike deploy to GitHub Pages

Versioning

Version is read from server/__init__.py. The logic:

  • If __version__ > last git tag → stable release (tags git, pushes :latest)

  • If __version__ == last git tag → dev release (appends .devYYYYMMDDHHMM, no :latest)

Bump __version__ in server/__init__.py to trigger a stable release on the next main push.


Project Structure

.
├── Dockerfile                   # Builds and runs the MCP server
├── pyproject.toml               # Project metadata, dependencies, tool config
├── server/
│   ├── __init__.py              # __version__ = "x.y.z"
│   └── main.py                  # FastMCP server — all tools live here
├── tests/
│   ├── Dockerfile               # Test runner image
│   ├── docker-compose.yaml      # mcp-server + test-runner services
│   ├── test_unit.py             # Tests for annualized_interest_rate
│   └── test_tools.py            # Tests for the remaining tools
├── docs/                        # MkDocs documentation site
├── reformat/                    # black + docformatter + isort container
├── lint/                        # ruff container
├── docs-validate/               # mkdocs build container
├── inspector/                   # MCP Inspector + server for visual testing
├── scripts/
│   └── semver_compare.py        # Used by CI to compare versions
└── .github/workflows/ci.yaml    # Full CI/CD pipeline

License

MIT

A
license - permissive license
-
quality - not tested
A
maintenance

Maintenance

Maintainers
Response time
3dRelease cycle
2Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

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/sinan-ozel/finance-tools'

If you have feedback or need assistance with the MCP directory API, please join our Discord server