Skip to main content

PyXIRR MCP Server

A Model Context Protocol (MCP) server that exposes pyxirr financial calculation functions as tools for use with GitHub Copilot and other MCP clients.

Features

This MCP server provides the following financial calculation tools:

Rate of Return Functions

  • xirr - Extended Internal Rate of Return for irregular cash flows
  • irr - Internal Rate of Return for periodic cash flows
  • mirr - Modified Internal Rate of Return

Net Present/Future Value Functions

  • xnpv - Net Present Value for irregular cash flows
  • npv - Net Present Value for periodic cash flows
  • xnfv - Net Future Value for irregular cash flows
  • nfv - Net Future Value for periodic cash flows

Time Value of Money Functions

  • fv - Future Value
  • pv - Present Value
  • pmt - Payment calculation
  • nper - Number of periods
  • rate - Interest rate calculation

Loan Analysis Functions

  • ipmt - Interest portion of a payment
  • ppmt - Principal portion of a payment
  • cumipmt - Cumulative interest paid
  • cumprinc - Cumulative principal paid

Installation

Prerequisites

  • Python 3.10 or higher
  • pip or uv package manager

Install from source

cd pyxirr-mcp-server
pip install -e .

Or with uv:

cd pyxirr-mcp-server
uv pip install -e .

Configuration

Create a .vscode/mcp.json file in your workspace (this is included in the project):

{
  "servers": {
    "pyxirr": {
      "type": "stdio",
      "command": "python",
      "args": ["-m", "pyxirr_mcp_server.server"],
      "cwd": "${workspaceFolder}/src"
    }
  }
}

This follows the VS Code MCP developer guidelines.

Alternative: Global VS Code settings

Add to your VS Code settings.json:

{
  "github.copilot.chat.mcpServers": {
    "pyxirr": {
      "command": "python",
      "args": ["-m", "pyxirr_mcp_server.server"],
      "cwd": "/path/to/pyxirr-mcp-server/src"
    }
  }
}

Claude Desktop

Add to your Claude Desktop configuration (claude_desktop_config.json):

{
  "mcpServers": {
    "pyxirr": {
      "command": "python",
      "args": ["-m", "pyxirr_mcp_server.server"],
      "cwd": "/path/to/pyxirr-mcp-server/src"
    }
  }
}

Usage Examples

Once configured, you can ask GitHub Copilot to perform financial calculations:

XIRR Calculation

"Calculate the XIRR for an investment of $10,000 on January 1, 2020, with returns of $5,750 on March 1, 2020, $4,250 on October 30, 2020, and $3,250 on February 15, 2021"

Mortgage Payment

"What's the monthly payment for a $300,000 mortgage at 6.5% annual rate over 30 years?"

Investment Future Value

"If I invest $500 per month for 20 years at 7% annual return, what will be the future value?"

NPV Analysis

"Calculate the NPV at 10% discount rate for an investment of $50,000 with annual returns of $15,000, $18,000, $20,000, and $22,000"

Cash Flow Conventions

Important: By convention in financial calculations:

  • Negative values represent money going OUT (investments, deposits, payments)
  • Positive values represent money coming IN (returns, income, withdrawals)

API Reference

All tools use camelCase parameter names following VS Code MCP guidelines.

xirr(dates, amounts, guess?)

Calculate the Internal Rate of Return for irregular cash flows.

xnpv(rate, dates, amounts)

Calculate the Net Present Value for irregular cash flows.

irr(amounts, guess?)

Calculate the Internal Rate of Return for periodic cash flows.

npv(rate, amounts, startFromZero?)

Calculate the Net Present Value for periodic cash flows.

mirr(amounts, financeRate, reinvestRate)

Calculate the Modified Internal Rate of Return.

fv(rate, nper, pmt, pv, pmtAtBeginning?)

Calculate the Future Value.

pv(rate, nper, pmt, fv?, pmtAtBeginning?)

Calculate the Present Value.

pmt(rate, nper, pv, fv?, pmtAtBeginning?)

Calculate the periodic Payment.

nper(rate, pmt, pv, fv?, pmtAtBeginning?)

Calculate the Number of Periods.

rate(nper, pmt, pv, fv?, pmtAtBeginning?, guess?)

Calculate the interest Rate per period.

ipmt(rate, per, nper, pv, fv?, pmtAtBeginning?)

Calculate the Interest portion of a specific payment.

ppmt(rate, per, nper, pv, fv?, pmtAtBeginning?)

Calculate the Principal portion of a specific payment.

cumipmt(rate, nper, pv, startPeriod, endPeriod, pmtAtBeginning?)

Calculate Cumulative Interest paid between periods.

cumprinc(rate, nper, pv, startPeriod, endPeriod, pmtAtBeginning?)

Calculate Cumulative Principal paid between periods.

nfv(rate, nper, amounts)

Calculate Net Future Value for uneven periodic payments.

xnfv(rate, dates, amounts)

Calculate Net Future Value for irregular cash flows.

License

MIT

Publishing

Releases of this package are automated by publish-pyxirr-mcp.yml. The workflow runs three sequential, gated stages:

  1. test — runs pytest. Required for everything downstream.
  2. pypi-publish — builds and uploads to PyPI using a project-scoped API token (PYPI_API_TOKEN secret).
  3. mcp-publish — registers server.json with the MCP registry using mcp-publisher and GitHub OIDC.

Releasing a new version

  1. Bump the version in three places (they must match — the workflow enforces it):
    • pyxirr-mcp-server/pyproject.toml → [project].version
    • pyxirr-mcp-server/server.json → top-level version and packages[0].version
  2. Merge to main.
  3. Tag and push:
    git tag pyxirr-v0.2.0
    git push origin pyxirr-v0.2.0
    
  4. The workflow runs end-to-end. Watch it under Actions → "Publish pyxirr-mcp-server".

One-time setup

PyPI API token

Trusted Publishing (OIDC) is not usable in this repo because the b2impact-com GitHub organisation is invisible to PyPI's anonymous GitHub API lookup (likely Enterprise Managed Users). The fallback is a project-scoped PyPI API token, gated by the pypi environment with required reviewers.

First publish (bootstrap, account-scoped token):

  1. Create a PyPI account if needed and verify you can log in at https://pypi.org/.
  2. Generate an account-scoped API token at https://pypi.org/manage/account/token/. (Project scope is not available until the project exists on PyPI.)
  3. In this repo: Settings → Environments → pypi → Add secret PYPI_API_TOKEN with the token value. Scope the secret to the pypi environment, not the repo, so it is only readable while the environment's required reviewer has approved the run.
  4. Run the publish workflow (push a pyxirr-v0.2.0 tag). Approve the environment gate.

After the first successful publish (lock down the token):

  1. On PyPI: revoke the account-scoped token.
  2. Generate a new token scoped to the pyxirr-mcp-server project only.
  3. Update the PYPI_API_TOKEN environment secret with the new value.

Rotate the project-scoped token periodically (e.g. yearly) or immediately if the secret is ever exposed.

GitHub Actions environments

Two environments gate the release. Create both under Settings → Environments, with the exact names below, and add required reviewers on each:

Environment Used by job Secret
pypi pypi-publish PYPI_API_TOKEN
mcp-registry mcp-publish MCP_REGISTRY_URL

Keeping them separate means PyPI credentials and the internal registry URL are never loaded into the same job, and each stage requires its own human approval click.

Security hardening (required before first release)

Configure these in repo Settings — they are not version-controlled and must be applied manually:

  1. Required reviewers on both environments (pypi and mcp-registry). Every publish stage then requires a human approval click. With token-based auth this is the primary mitigation against secret misuse — without it, any workflow run that reaches a publish job can read the secret.
  2. Scope each secret to its environment, not the repo: PYPI_API_TOKEN on pypi, MCP_REGISTRY_URL on mcp-registry. This way neither secret is readable from any other workflow, job, branch, or PR.
  3. Tag protection rule for pyxirr-v* (Settings → Rules → Rulesets, target Tags). Restricts who can push release tags.
  4. Branch protection on main: require PR review + status checks (incl. pyxirr-mcp-server-tests from ci.yml) before merge.
  5. Dependabot is configured (.github/dependabot.yml) to weekly bump GitHub Actions and Python deps. Review and merge those PRs promptly; the workflow uses mcp-publisher pinned via the MCP_PUBLISHER_VERSION env in the workflow file.
  6. Pre-release audit: the build job already lists every file in the wheel + sdist and computes SHA256s. Inspect the workflow log on the first release to confirm only expected files ship.

MCP registry

The target registry URL is supplied via the environment secret MCP_REGISTRY_URL on the mcp-registry environment (Settings → Environments → mcp-registry → Add secret). It points to an internal organisational registry, so it is stored as a secret (masked in workflow logs) and scoped to the publish environment only — not as a repo-wide secret or variable. The workflow fails fast if the secret is missing.

The registry must be configured to accept GitHub OIDC tokens. The server name io.github.b2impact-com/pyxirr-mcp-server matches the OIDC-granted namespace io.github.{org}/*.

Ownership verification

PyPI ownership is verified by the MCP registry via the mcp-name: marker in this README (line 3). The marker is shipped inside the wheel because hatchling includes README.md. Do not remove it.

Credits

This MCP server is powered by pyxirr, a Rust-powered collection of financial functions.

Metadata

Release files for pyxirr-mcp-server 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pyxirr-mcp-server 0.2.0
File Size Uploaded Provenance Actions
pyxirr_mcp_server-0.2.0.tar.gz 14.0 kB Without provenance Details for pyxirr_mcp_server-0.2.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for pyxirr-mcp-server 0.2.0
File Interpreter ABI Platform Actions
pyxirr_mcp_server-0.2.0-py3-none-any.whl Python 3 none any Details for pyxirr_mcp_server-0.2.0-py3-none-any.whl

Total release size: 23.3 kB

Release files / pyxirr_mcp_server-0.2.0.tar.gz

Download URL pyxirr_mcp_server-0.2.0.tar.gz
Size 14.0 kB
Tags Source
SHA-256 checksum
How to use checksums
a444b312361549aadfb224f092dfa58ab06718de69e3e1913aa5447668ea997d
BLAKE2b-256 checksum
How to use checksums
b2133c230712472168500a432077e63375a62b818b12ec9243f351feacd48da5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.12

Release files / pyxirr_mcp_server-0.2.0-py3-none-any.whl

Download URL pyxirr_mcp_server-0.2.0-py3-none-any.whl
Size 9.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
44d0e08b61897ea3dd216f06a80eecd336e95ceab8c1156e2da6fbaf82245408
BLAKE2b-256 checksum
How to use checksums
4745580c5e9ce61d30bf2c6a403e2d3af18697c106d9a4d3abb0c5f0eabdb1a5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.12

Security for pyxirr-mcp-server 0.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page