Planners About

MCP Server Quickstart

Connect the Digital Calculator MCP server to your AI tool in under 5 minutes. The server is hosted at https://mcp.digitalcalculator.info/mcp (Streamable HTTP, POST, no auth) — there is nothing to install for the recommended path.

What you'll get

10 tools — 9 calculator tools plus money_flow_map, an interactive money-flow budget map — usable directly from claude.ai, Claude Desktop, MCP Inspector, any Streamable HTTP MCP client, or plain curl. Free — no signup, no API key. The hosted endpoint is governed by its hosted-API terms (LICENSE-API.md — rate limits + acceptable use); the npm shim package is MIT-licensed (see the npm package). One additional tool, generate_report, is Bearer-tier only and renders branded PDF reports server-side — see Server-rendered PDF reports below.

Option 1 — Connect from your AI client (recommended)

Time: ~1 minute in every client below. No install required for the HTTP-native clients (Claude Desktop/claude.ai, Claude Code, ChatGPT); Cursor, VS Code, and Windsurf edit a local config file or follow an install link. The server needs no authentication for anonymous use — leave any auth field blank.

Every client below points at the same JSON shape. The canonical block (works as-is for Claude Desktop's config file, and Cursor's mcp.json):

json
{
  "mcpServers": {
    "digitalcalculator": {
      "url": "https://mcp.digitalcalculator.info/mcp"
    }
  }
}

If you use Claude Code, skip the config file entirely — one command adds the server:

bash
claude mcp add --transport http digitalcalculator https://mcp.digitalcalculator.info/mcp

Claude Desktop & claude.ai (Custom Connectors)

In claude.ai or Claude Desktop, open Settings → Connectors, click "Add custom connector", and paste the server URL:

text
https://mcp.digitalcalculator.info/mcp

No authentication is required — leave any auth fields blank and save. Start a new conversation and ask "what MCP tools do you have access to?" — Claude should list the 9 calculator tools plus money_flow_map (plan_retirement_income, mortgage_monthly_payment, money_flow_map, and more). If they don't appear, check that the connector is enabled in the conversation's tools menu. Then try:

Example prompt

What's the monthly payment on a $400,000 mortgage at 6.5% over 30 years?

Claude will invoke mortgage_monthly_payment and return a structured answer with the math + the YMYL disclaimer.

Claude Code

One command, no config file:

bash
claude mcp add --transport http digitalcalculator https://mcp.digitalcalculator.info/mcp

The default scope is the current project; add --scope user to make the server available across every project. See Claude Code's MCP docs for scopes and auth headers.

Cursor

Two ways in: a one-click install link, or the config file.

Install link — Cursor's deeplink format is cursor://anysphere.cursor-deeplink/mcp/install?name=$NAME&config=$BASE64_ENCODED_CONFIG, where $BASE64_ENCODED_CONFIG is the base64 encoding of {"url":"https://mcp.digitalcalculator.info/mcp"}. For this server that resolves to:

text
cursor://anysphere.cursor-deeplink/mcp/install?name=digitalcalculator&config=eyJ1cmwiOiJodHRwczovL21jcC5kaWdpdGFsY2FsY3VsYXRvci5pbmZvL21jcCJ9

Config file — edit ~/.cursor/mcp.json:

json
{
  "mcpServers": {
    "digitalcalculator": {
      "url": "https://mcp.digitalcalculator.info/mcp"
    }
  }
}

Source: Cursor — MCP Install Links.

VS Code

Run MCP: Add Server from the Command Palette, or add the server from a terminal:

bash
code --add-mcp "{\"name\":\"digitalcalculator\",\"type\":\"http\",\"url\":\"https://mcp.digitalcalculator.info/mcp\"}"

Or edit .vscode/mcp.json directly — note the top-level key is servers, not mcpServers:

json
{
  "servers": {
    "digitalcalculator": {
      "type": "http",
      "url": "https://mcp.digitalcalculator.info/mcp"
    }
  }
}

Source: VS Code — Add and manage MCP servers. VS Code also documents a vscode:mcp/install install-link scheme elsewhere in its ecosystem; the CLI and config-file paths above are the ones confirmed on that page, so start there.

Windsurf

Edit ~/.codeium/windsurf/mcp_config.json (create it if it doesn't exist) — Windsurf's remote-server field is serverUrl, not url:

json
{
  "mcpServers": {
    "digitalcalculator": {
      "serverUrl": "https://mcp.digitalcalculator.info/mcp"
    }
  }
}

Or use Command Palette → "Windsurf: Configure MCP Servers" to open the file with editor support.

ChatGPT (Developer mode / custom connector)

In ChatGPT: Settings → Connectors → Advanced (or Settings → Apps & Connectors → Advanced settings, depending on your account), turn on Developer mode, then Settings → Connectors → "Add custom connector." Give it a name and the server URL, and choose authentication None (this server takes no auth for anonymous use):

text
https://mcp.digitalcalculator.info/mcp

Developer mode requires a ChatGPT Pro, Team, Enterprise, or Edu account. Source: OpenAI Help Center — Developer mode and MCP apps in ChatGPT.

Option 2 — MCP Inspector (for debugging)

Time: ~1 minute.

The official MCP Inspector is a browser-based debugging UI for MCP servers.

bash
npx @modelcontextprotocol/inspector

In the Inspector UI, select the Streamable HTTP transport, enter https://mcp.digitalcalculator.info/mcp, and connect. You'll see:

  • All 10 tools listed in the Tools tab
  • The statutory reference data (dc://irs/limits/2026, dc://irs/uniform-lifetime, dc://ssa/bend-points/2026, with the 2025 version it supersedes and the rule-year diff dc://ssa/bend-points/diff/2025..2026), the YMYL disclaimer (dc://disclaimers/ymyl), and the methodology manifest (dc://methodologies/manifest) in the Resources tab
  • The three server prompts (retirement-readiness-review, conversion-window-analysis, withholding-checkup) in the Prompts tab
  • The MCP protocol handshake logged in the bottom panel

Click any tool, fill the input form, and hit "Call Tool" to invoke it. Useful for verifying tool schemas before integrating in your own client.

Option 3 — npm shim for stdio-only clients

Some MCP clients and agent frameworks only speak MCP over stdio. The @markcolabs/mcp package (v0.4+) is a thin stdio→HTTPS shim: it runs locally, accepts stdio JSON-RPC, and forwards every call to the hosted endpoint.

bash
npx @markcolabs/mcp

For frameworks like LangChain's MCP adapter or the OpenAI Agents SDK, configure the server with command: "npx" and args: ["@markcolabs/mcp"]. If your client supports Streamable HTTP natively (as Claude's Custom Connectors do), prefer Option 1 — it skips the local process entirely.

Option 4 — Plain HTTP (no MCP client needed)

Time: ~30 seconds, just curl.

The endpoint speaks JSON-RPC 2.0 over plain HTTP POST, so any HTTP client can call it. Use this for server-side scripts, CI checks, or backend fetch calls.

bash
curl -X POST https://mcp.digitalcalculator.info/mcp \
  -H 'Content-Type: application/json' \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "mortgage_monthly_payment",
      "arguments": {
        "principal": 400000,
        "annual_rate_percent": 6.5,
        "term_years": 30
      }
    }
  }'

Response (HTTP 200) — a JSON-RPC Result, with resultType as a sibling of content and structuredContent (never nested inside it — see the Result envelope):

json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "content": [ { "type": "text", "text": "{ ...same JSON as structuredContent below... }" } ],
    "structuredContent": {
      "result": { "monthlyPayment": 2528.27, "totalInterest": 510177.95, "totalPaid": 910177.95 },
      "disclaimer": "Estimates only — for educational purposes...",
      "methodology": {
        "url": "https://www.digitalcalculator.info/mortgage-calculator/methodology/",
        "version": "2026-05-09"
      },
      "rule_year": 2026,
      "sources": ["dc://methodologies/manifest"],
      "provenance": [],
      "calculatedAt": "2026-08-07T18:42:11.123Z",
      "engineVersion": "1.0.1"
    },
    "resultType": "complete"
  }
}

REST companion

A REST API at https://api.digitalcalculator.info/v1/tools/{alias}/calculate runs the same engines and returns the same response envelope without the JSON-RPC wrapper — including compatibility aliases for every pre-1.0 tool. See the API Reference.

Example tool calls

All examples use the same JSON-RPC tools/call wrapper — only params.name and params.arguments change. A selection across the 10 tools:

Growth projection (nominal + inflation-adjusted)

bash
curl -X POST https://mcp.digitalcalculator.info/mcp \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"project_growth","arguments":{"balance":10000,"annual_contribution":6000,"annual_rate_percent":7,"years":30,"inflation_rate_percent":3}}}'

Linked retirement-income plan (401(k) + Social Security + RMD)

bash
curl -X POST https://mcp.digitalcalculator.info/mcp \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"plan_retirement_income","arguments":{"include":["accumulation","social_security","rmd"],"birth_year":1991,"balance":25000,"annual_salary":80000,"contribution_percent":6,"employer_match_percent":50,"employer_match_limit_percent":6,"annual_return_percent":7,"retirement_age":65,"claim_age":67}}}'

RMD-only question ("when do RMDs start?")

bash
curl -X POST https://mcp.digitalcalculator.info/mcp \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"plan_retirement_income","arguments":{"include":["rmd"],"birth_year":1968,"balance":500000}}}'

Contribution eligibility (Roth IRA with phase-out)

bash
curl -X POST https://mcp.digitalcalculator.info/mcp \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"check_contribution_eligibility","arguments":{"kind":"roth_ira","birth_year":1974,"filing_status":"single","magi":120000}}}'

Emergency fund recommendation

bash
curl -X POST https://mcp.digitalcalculator.info/mcp \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"emergency_fund_recommendation","arguments":{"monthly_expenses":4500,"current_savings":8000,"monthly_savings":600,"employment_type":"self-employed","income_earners":"single","dependents":2,"savings_apy":4.3}}}'

Loan monthly payment

bash
curl -X POST https://mcp.digitalcalculator.info/mcp \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"loan_monthly_payment","arguments":{"loan_amount":25000,"annual_rate_percent":8.5,"term_years":5}}}'

For all 10 tools with full input schemas, output payload shapes, and per-tool detail, see the API Reference. Every argument name above is snake_case — the four single-quantity calculator tools also accept their older camelCase spellings (deprecated, still working) via the alias policy.

Server-rendered PDF reports (generate_report)

Everything above runs on the anonymous surface. One additional tool, generate_report, is available to Bearer-tier sessions only: it renders a vector-text PDF report for a report-capable calculator on our servers and returns a short-lived download link. Use it when an agent or backend needs to hand a user a client-ready document. The website's own calculator pages do not use this path — their PDF button renders the same document in the browser, on-device.

Prerequisite: a Bearer key

Every call needs an Authorization: Bearer dc_bearer_… header. dc_bearer_ keys are the secret key class — see Pricing for Bearer-tier access. The free self-serve dc_pub_ keys and anonymous sessions do not unlock this tool: without a Bearer token it is absent from tools/list, and calling it anyway returns a structured authentication_required error. Bearer calls are server-to-server today — the API's CORS policy does not allow the Authorization header from browsers — so call from a backend, CLI, or MCP client, and keep the key out of client-side source.

Step 1 — call the tool

Two required arguments: tool, a report-capable alias (mortgage, loan, retirement-401k, education, credit-card), and input, the same input object that tool's calculator accepts. input is deliberately not re-spelled to snake_case — it is the REST report body carried verbatim (see the Amendment B exception), so it keeps its original camelCase field names below even though the calculator tools above are now snake_case. Over MCP:

bash
curl -X POST https://mcp.digitalcalculator.info/mcp \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer dc_bearer_YOUR_KEY' \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "generate_report",
      "arguments": {
        "tool": "mortgage",
        "input": {
          "principal": 400000,
          "annualRatePercent": 6.5,
          "termYears": 30
        }
      }
    }
  }'

Or the REST twin on the same host — same rendering pipeline, same envelope, with the bare input JSON as the request body:

bash
curl -X POST https://mcp.digitalcalculator.info/v1/reports/mortgage \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer dc_bearer_YOUR_KEY' \
  -d '{"principal":400000,"annualRatePercent":6.5,"termYears":30}'

Step 2 — download the PDF

A success returns the report envelope (over MCP, the download URL is also emitted as a resource_link content block):

json
{
  "report": {
    "url": "https://….s3.amazonaws.com/reports/mortgage/<hash>.pdf?X-Amz-…",
    "expiresInSeconds": 900,
    "cached": false,
    "contentType": "application/pdf",
    "cacheKey": "<hash>"
  },
  "tool": "mortgage",
  "engineVersion": "1.0.1",
  "calculatedAt": "2026-08-17T00:00:00.000Z",
  "disclaimer": "Estimates only — see methodology.",
  "methodology": { "url": "https://www.digitalcalculator.info/mortgage-calculator/methodology/", "version": "2026-05-09" }
}

Fetch report.url before it expires (expiresInSeconds — 15 minutes by default). Identical inputs are served from the artifact cache (cached: true): re-requesting after the link expires returns a fresh URL without re-rendering, and doesn't change the numbers. Reports are metered against a separate daily report quota on your key (default 25 per UTC day), distinct from your calculator-call allowance; the 5-minute short-term window is shared with your other calls.

Step 3 — branding (BrandConfig)

A Bearer key can carry a BrandConfig — a white-label configuration stored on the key record server-side. There is no per-request brand parameter and no code change on your side: once your key carries a BrandConfig, the same generate_report call renders the PDF with your branding. All five fields are optional; any subset works.

BrandConfig fields, their constraints, and what each changes on the rendered report
FieldConstraintsWhat it changes
companyNameup to 60 charactersReplaces "Digital Calculator" as the report's branding name
taglineup to 80 charactersReplaces the tagline under the branding name
logoUrlhttps URL of an image (png/jpg/gif/webp/svg) on a public hostAdds your logo above the branding name, rendered up to 48px tall / 180px wide
primaryColor6-digit hex (#rrggbb)The report's slate chrome: header rule, branding name, results-table header bar, disclaimer bar
accentColor6-digit hex (#rrggbb)The copper accent on the input summary

To set or change it: include these fields when you request a Bearer key, or email admin@markcolabs.com from the address that requested the key to add or update them on an existing key — the change is applied to the key record, and your next render carries it. Each field is validated independently, so an invalid logoUrl drops only the logo, never the whole config. A branding change automatically produces fresh renders — the report cache is partitioned per brand, so you are never served a stale-brand PDF.

Branding is presentation-only

BrandConfig restyles the report's chrome and identity — name, tagline, logo, colors — and nothing else. It never changes a financial figure, an input value, or a table cell, and the "Not financial advice" core disclaimer is non-removable on every branded render.

Full input schema, output shape, and error codes: generate_report in the API Reference.

Common errors

Unknown tool: <name>

You're calling a tool name that doesn't exist. Tool names are snake_case (e.g., mortgage_monthly_payment). The legacy dot-notation names from the v0.2.x stdio package (e.g., dc.calculator.mortgage.monthlyPayment) were retired at the hosted-server cutover — if you integrated against them, switch to the snake_case names listed in the API Reference. The npm version history has full migration notes.

INPUT_VALIDATION with field: "<name>"

Input failed schema validation. This is always HTTP 200 with result.isError: true, never HTTP 400. As of contract 1.3.0, the message names which of five failure classes happened, so a model can fix the right thing on retry instead of guessing a different number when the real problem was a different key:

  • Missing a required field — "principal is required"
  • Wrong type — "principal must be a number" (also an integer / a string / a boolean, matching the field's declared type)
  • Unknown argument, close match — "unknown argument 'principa' — did you mean 'principal'? mortgage_monthly_payment accepts only: principal, annual_rate_percent, term_years."
  • Unknown argument, no close match — "unknown argument 'down_payment' — no close match. mortgage_monthly_payment accepts only: principal, annual_rate_percent, term_years."
  • Genuinely out of range (unchanged since before 1.3.0) — "principal must be between 0 and 100000000"

The field property identifies which input triggered the error. Check the API Reference for valid ranges and the current snake_case argument names.

BUSINESS_RULE error

Inputs are individually valid but the combination doesn't produce a meaningful result (e.g., 401(k) retirementAge not greater than currentAge). Fix the cross-field issue.

Rate limit (HTTP 429)

You hit either the shared endpoint throttle (100 requests/min across all callers) or your own per-caller allowance — anonymously, 500 tools/call calls per UTC day per IP and 30 per 5-minute window. As of contract 1.2.0, only tools/call is metered — connecting, listing tools, and reading resources never count against either ceiling. Back off and retry: the 429 still carries Retry-After plus X-RateLimit-Limit / -Remaining / -Reset, unchanged. The body shape differs by route: the REST route keeps {"error":{"code":"RATE_LIMIT","retriable":true,...}}; on /mcp it is now a JSON-RPC error object, {"jsonrpc":"2.0","id":<id>,"error":{"code":-32000,"message":"rate_limited: slow down.","data":{"reason":"rate_limited","scope":"window","limit":30,"retry_after_seconds":N,...}}} — see Status mapping. Sustained higher volume is what the Bearer tiers are for, or email us.

Bearer credential rejected (HTTP 401)

Only relevant if you sent an Authorization: Bearer header (anonymous calls are never affected). As of contract 1.2.0, /mcp returns a JSON-RPC error, code -32001, with the reason in error.data.reason (invalid_token, token_revoked, or token_expired); the REST route keeps its unwrapped {"error":{"code":"UNAUTHORIZED",...}} body. No rate-limit headers accompany a 401.

Next steps

Building something interesting with the MCP server? We'd love to hear about it — email admin@markcolabs.com.