@colgonics/finance-calc-mcp
v1.0.0
Published
Local MCP server for basic arithmetic and common finance calculations (loans, interest, depreciation, dividend MTM). Uses decimal.js for precision-safe money math — no float drift.
Maintainers
Readme
finance-calc-mcp (Node.js)
A local MCP server that provides basic arithmetic plus common finance
calculations. Same calculations as the Python version, in Node. Uses
decimal.js throughout — no floating-point errors in money math.
Install
cd finance-calc-mcp
npm installThat's it. No build step (this is plain ES modules, no TypeScript).
Verify it works:
npm testYou should see "All tests passed." Optionally, sanity-check the live MCP
server against itself by running node probe.js, which spawns the server
as a subprocess and exercises a couple of tools.
Wire into Claude Desktop
Edit claude_desktop_config.json:
- Windows:
%APPDATA%\Claude\claude_desktop_config.json - macOS:
~/Library/Application Support/Claude/claude_desktop_config.json
Add:
{
"mcpServers": {
"finance-calc": {
"command": "node",
"args": ["C:/absolute/path/to/finance-calc-mcp/src/index.js"]
}
}
}Restart Claude Desktop. The 17 finance tools should show up.
Use from your own Node.js code
You don't need Claude in the loop — you can call the server directly from
any Node program using the MCP client SDK. See probe.js for a working
example. The pattern:
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
const transport = new StdioClientTransport({
command: "node",
args: ["./src/index.js"],
});
const client = new Client({ name: "my-app", version: "1.0.0" }, { capabilities: {} });
await client.connect(transport);
const result = await client.callTool({
name: "loan_payment",
arguments: { principal: 200000, annual_rate_pct: 6.0, term_months: 360 },
});
console.log(result.content[0].text); // "1199.10"
await client.close();Tools
Basic: add, subtract, multiply, divide, power
Loans:
loan_payment(principal, annual_rate_pct, term_months)loan_amortization_summary(...)loan_remaining_balance(..., payments_made)
Interest:
simple_interest(principal, annual_rate_pct, years)compound_interest(principal, annual_rate_pct, years, compounds_per_year=12)daily_interest_accrual(principal, annual_rate_pct, days, day_count_basis=360)— A/360 or A/365
Depreciation:
depreciation_straight_line(cost, salvage_value, useful_life_years)depreciation_declining_balance(cost, salvage_value, useful_life_years, factor=2.0)— full year-by-year schedule
Tip: tip(bill, tip_pct=18, split_n=1)
Dividend MTM: dividend_mark_to_market(shares, dividend_per_share, cost_basis_per_share, current_price_per_share, dividends_received=0)
PV/FV:
present_value(future_amount, annual_rate_pct, years, compounds_per_year=1)future_value(present_amount, annual_rate_pct, years, compounds_per_year=1)
Why Decimal not float
Money math in floats has well-known precision bugs (0.1 + 0.2 ≠ 0.3).
Every calculation in this server runs through decimal.js with 28 digits
of precision and explicit rounding at the boundary. Inputs come in as
floats over the JSON wire — they're converted to Decimal on the way in so
nothing accumulates float drift downstream.
