Koskamo

theluckystrike Dunning Letters MCP

Automates payment reminders for overdue invoices by generating reminder 1, reminder 2, and final notice letters on a configurable schedule. It tracks aging, calculates late fees, and manages the escalation ladder without emailing directly, allowing users to render letters in Markdown or HTML.

Endpoint and access

No sign-in to connect and list tools. Individual tools may still need a vendor account, credentials, or permissions; check the documented prerequisites.

theluckystrike Dunning Letters MCP logo, by theluckystrikeCommunity listingStreamable HTTPNo sign-inEndpoint checked 2026-11-06Published by theluckystrike
You need:Get a free token with one requestcurl -X POST https://mcp.zovo.one/mcp/token
MCP endpoint (Streamable HTTP)
https://mcp.zovo.one/mcp/dunning-letters
Vendor documentation

What its tools do

11 tools, grouped by the hints the server advertises. Hints are self-declared, not verified behavior.

11 of 11 have a description · 11 of 11 declare behavior hints · 9 of 10 with parameters document them all

Checks and signals

Each line is separate evidence, not a trust score.

  • Passed Endpoint answered the live check ·
  • Availability 1 of 1 checks passed in 30 days

What you can do with it

  • Generate reminder 1, 2, and final notice letters for overdue invoices
  • Get a daily chase list of invoices crossing escalation thresholds
  • Calculate aging summaries with buckets for unpaid amounts
  • Record payments to lower outstanding balances and close ladders

Source and maintenance

Community listingRegistry 0.23.0
Maintenance checked

Protocol and capabilities

Server
mcp-dunning-letters 0.22.6
MCP protocol negotiated in check
2025-11-25
Tools
11 advertised
Resources
2 advertised
Resource templates
0 advertised
Prompts
2 advertised
Server-advertised capabilities
{
  "tools": {
    "listChanged": true
  },
  "prompts": {
    "listChanged": true
  },
  "resources": {
    "listChanged": true
  }
}

Server-provided instructions

Untrusted server output shown for inspection. It is not Koskamo guidance and is excluded from knowledge search.

Chasing unpaid invoices with a three-letter escalation ladder. It covers registering unpaid invoices with amount and due date, part or full payments, reminder, firm reminder and final notice letters as Markdown or printable HTML, the dates letters went out, the day's chase list, invoices past due and the ageing of what is owed. Letters are drafted here and never sent; sending is the user's act. Records are stored per user account on McpStamp's hosted service. The free tier chases 3 invoices at once. One lifetime key unlocks this server and all 58 others: https://mcp.zovo.one/buy/bundle?src=instr.dunning-letters

Tools

11 advertised

invoice_register — Register an unpaid invoice to chase
Advertised by the server during the last successful anonymous check.

Start chasing an unpaid invoice: register the client, the invoice reference, the amount in integer cents, the currency and the due date, and get the three-letter escalation schedule (reminder 1, reminder 2, final notice) with the date each falls due. Free tier: 3 unpaid invoices chased at once.

invoice_register input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "client",
    "reference",
    "amount_minor",
    "currency",
    "due"
  ],
  "properties": {
    "due": {
      "type": "string",
      "maxLength": 10,
      "description": "The date payment fell due, YYYY-MM-DD. The ladder is anchored to this date"
    },
    "gaps": {
      "type": "array",
      "items": {
        "type": "integer",
        "maximum": 365,
        "minimum": 1
      },
      "maxItems": 3,
      "minItems": 3,
      "description": "Days after the due date at which reminder 1, reminder 2 and the final notice fall due, strictly increasing. Default [7, 14, 21]"
    },
    "note": {
      "type": "string",
      "maxLength": 2000
    },
    "client": {
      "type": "string",
      "maxLength": 200,
      "description": "Who owes the money, e.g. Acme Ltd"
    },
    "issued": {
      "type": "string",
      "maxLength": 10,
      "description": "The date the invoice was issued, YYYY-MM-DD, for the letter's reference line"
    },
    "currency": {
      "type": "string",
      "pattern": "^[A-Za-z]{3}$",
      "description": "ISO code the invoice was issued in"
    },
    "reference": {
      "type": "string",
      "maxLength": 200,
      "description": "The invoice number being chased, e.g. INV-1042"
    },
    "amount_minor": {
      "type": "integer",
      "maximum": 100000000000000,
      "minimum": 1,
      "description": "The invoice amount in whole minor units (integer cents). 125000 is USD 1,250.00"
    },
    "duplicate_ok": {
      "type": "boolean",
      "description": "Register even though an identical invoice is already on the register. Default false"
    },
    "late_fee_percent_per_month": {
      "type": "number",
      "maximum": 100,
      "description": "Late payment interest your terms allow, percent per month, simple and pro-rata. When set, reminder 2 and the final notice state the accrued figure",
      "exclusiveMinimum": 0
    }
  }
}
invoice_register annotations
{
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": false,
  "destructiveHint": false
}
payment_record — Record a payment received
Advertised by the server during the last successful anonymous check.

Record money received against a chased invoice, in whole MINOR units: a part payment lowers what is still chased, a payment that covers the balance closes the ladder and frees the free-tier slot. Returns the outstanding amount.

payment_record input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "invoice",
    "amount_minor"
  ],
  "properties": {
    "date": {
      "type": "string",
      "maxLength": 10,
      "description": "The date the money arrived, YYYY-MM-DD. Default today"
    },
    "note": {
      "type": "string",
      "maxLength": 2000,
      "description": "How it was paid, e.g. Bank transfer, or what it was against"
    },
    "invoice": {
      "type": "string",
      "maxLength": 200,
      "description": "The chased invoice: its id (DUN-2026-0001) or its invoice reference"
    },
    "amount_minor": {
      "type": "integer",
      "maximum": 100000000000000,
      "minimum": 1,
      "description": "What was received, in whole minor units"
    }
  }
}
payment_record annotations
{
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": false,
  "destructiveHint": false
}
letter_render — Generate the chase letter for the current stage
Advertised by the server during the last successful anonymous check.

Chase an unpaid invoice: generate the letter for the current stage of the ladder -- reminder 1 (polite), reminder 2 (firm, with the late fees note) or the final notice (before-action wording) -- as Markdown or as self-contained printable HTML. Nothing is emailed or sent anywhere: this server produces the letter text, and sending it is your act. Record the sending with letter_sent so the ladder advances.

letter_render input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "invoice"
  ],
  "properties": {
    "on": {
      "type": "string",
      "maxLength": 10,
      "description": "The letter's date, YYYY-MM-DD; late fees accrue to it and the final-notice deadline is 7 days after it. Default today"
    },
    "stage": {
      "anyOf": [
        {
          "type": "number",
          "const": 1
        },
        {
          "type": "number",
          "const": 2
        },
        {
          "type": "number",
          "const": 3
        }
      ],
      "description": "Render a specific stage instead of the one currently due, to preview or to re-issue a letter already sent"
    },
    "format": {
      "enum": [
        "markdown",
        "html"
      ],
      "type": "string",
      "description": "markdown (default) or html: a self-contained printable page with no external anything"
    },
    "invoice": {
      "type": "string",
      "maxLength": 200,
      "description": "The chased invoice: its id (DUN-2026-0001) or its invoice reference"
    }
  }
}
letter_render annotations
{
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": false,
  "destructiveHint": false
}
letter_sent — Record that a letter was sent
Advertised by the server during the last successful anonymous check.

Record that a chase letter was actually sent, with its date, so the ladder advances to the next stage. Letters go out in order: reminder 2 cannot be recorded before reminder 1. Returns what is due next and when.

letter_sent input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "invoice"
  ],
  "properties": {
    "sent": {
      "type": "string",
      "maxLength": 10,
      "description": "The date it was sent, YYYY-MM-DD. Default today"
    },
    "stage": {
      "anyOf": [
        {
          "type": "number",
          "const": 1
        },
        {
          "type": "number",
          "const": 2
        },
        {
          "type": "number",
          "const": 3
        }
      ],
      "description": "Which letter went out. Default the lowest unsent stage"
    },
    "invoice": {
      "type": "string",
      "maxLength": 200,
      "description": "The chased invoice: its id (DUN-2026-0001) or its invoice reference"
    }
  }
}
letter_sent annotations
{
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": false,
  "destructiveHint": false
}
overdue_list — List overdue invoices
Advertised by the server during the last successful anonymous check.
Advertised read-only

Every unpaid invoice past its due date: how many days late, what is still owed, which letters have gone out, and what is due next and when. Sorted by days late, worst first.

overdue_list input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "properties": {
    "on": {
      "type": "string",
      "maxLength": 10,
      "description": "The date to judge lateness against, YYYY-MM-DD. Default today"
    },
    "limit": {
      "type": "integer",
      "maximum": 2000,
      "minimum": 1,
      "description": "Maximum rows, default and ceiling 2000"
    }
  }
}
overdue_list annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
aging_summary — Aging summary of what is owed
Advertised by the server during the last successful anonymous check.
Advertised read-only

The aging summary across every unpaid invoice: current, 1-30, 31-60, 61-90 and 91+ day buckets, with counts and totals in integer cents, per currency. This is the answer to "how much am I owed, and how stale is it".

aging_summary input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "properties": {
    "on": {
      "type": "string",
      "maxLength": 10,
      "description": "The date to age against, YYYY-MM-DD. Default today"
    }
  }
}
aging_summary annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
chase_today — What to chase today
Advertised by the server during the last successful anonymous check.

The day's chase list: which invoices cross an escalation threshold today, which letter to send each and how long it has been waiting, what falls due in the next few days, and which invoices have had all three letters and need a decision outside this server.

chase_today input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "properties": {
    "on": {
      "type": "string",
      "maxLength": 10,
      "description": "The date to run the list for, YYYY-MM-DD, e.g. to see what Monday will need. Default today"
    },
    "within_days": {
      "type": "integer",
      "maximum": 90,
      "minimum": 0,
      "description": "How far ahead to list letters coming due, default 7 days"
    }
  }
}
chase_today annotations
{
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": false,
  "destructiveHint": false
}
invoice_status — The full state of one chased invoice
Advertised by the server during the last successful anonymous check.
Advertised read-only

One chased invoice in full: what was billed, what has been paid and what is still owed, every letter sent with its date, the escalation schedule with each stage's state, and what happens next and when.

invoice_status input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "invoice"
  ],
  "properties": {
    "on": {
      "type": "string",
      "maxLength": 10,
      "description": "The date to judge lateness against, YYYY-MM-DD. Default today"
    },
    "invoice": {
      "type": "string",
      "maxLength": 200,
      "description": "The chased invoice: its id (DUN-2026-0001) or its invoice reference"
    }
  }
}
invoice_status annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
invoice_delete — Delete an invoice from the register
Advertised by the server during the last successful anonymous check.
Advertised destructive

Delete an invoice entered wrongly, by id or reference: the record, its payments and its letter history. The id is not reissued, so a gap in the DUN series is the record that a deletion happened.

invoice_delete input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "invoice"
  ],
  "properties": {
    "invoice": {
      "type": "string",
      "maxLength": 200,
      "description": "The chased invoice: its id (DUN-2026-0001) or its invoice reference"
    }
  }
}
invoice_delete annotations
{
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": false,
  "destructiveHint": true
}
license_status — License status
Advertised by the server during the last successful anonymous check.
Advertised read-only

Report this endpoint's licence state for your token as JSON: the product, the tier free or pro, why it is not Pro, and the checkout URL. Call it to explain a free-tier refusal. No arguments, nothing changes.

license_status input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "properties": {}
}
license_status annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
license_activate — Activate license
Advertised by the server during the last successful anonymous check.

Turn Pro on for this connection with key, an MCPL1.<payload>.<signature> issued at checkout for this server or the bundle. Data under your token stays; a wrong or expired key changes nothing. license_status confirms it.

license_activate input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "key"
  ],
  "properties": {
    "key": {
      "type": "string",
      "description": "License key from checkout, MCPL1.<payload>.<signature>"
    }
  }
}
license_activate annotations
{
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": false,
  "destructiveHint": false
}

Prompts

2 advertised

upgrade_to_pro — Explain the upgrade

Advertised by the server during the last successful anonymous check.

Explain what Pro on the dunning-letters server costs and exactly what the user has to do, without leaving the conversation.

feature
The capped feature that prompted this, if there was one
weekly_chase — Run the weekly chase

Advertised by the server during the last successful anonymous check.

List what is overdue, send every letter that is due, and record the sendings.

No arguments advertised.

Resources

2 advertised

pricing — Pricing and upgrade

Advertised by the server during the last successful anonymous check.

What dunning-letters costs, what Pro unlocks, the checkout link that carries this connection's token, and the one step a person has to take. Machine-readable; read it before telling a user how to lift a free-tier cap.

pricing URI
pricing://dunning-letters

MIME type: application/json

ladder — The escalation ladder this server runs

Advertised by the server during the last successful anonymous check.

The three stages, when each falls due, what each letter says, the free tier, and the one document this server writes.

ladder URI
dunning://ladder

MIME type: application/json

90-day uptime

A lightweight connection check about every six hours, sampled on hosts with many listings. It shows the server answered, not that its tools work.

Too few checks for a percentage yet (1 of 1 answered).

  1. 2026-11-07: 1 of 1 checks answered

30-day availability

Aggregated from read-only remote checks; this is not a tool-execution or security guarantee.

Successful checks
1 of 1 (100%)
Average latency
333 ms
95th percentile latency
333 ms

Maintenance history

Public check and source-refresh events. Editorial and ownership records remain private.

  • · probe · passed · 333 ms · metadata changed · 11 tool(s), 2 resource(s), 0 resource template(s), 2 prompt(s)

Connect from your client

Each snippet registers the same endpoint; pick the client you use.

This server is operated by the named third party. Listing and endpoint checks are not an endorsement or a security audit. Review the operator's permissions, terms, and data handling before connecting. How listings are checked and corrected.

Claude Code

Run this once in a terminal. It registers the remote server. Use --scope project to write .mcp.json for the repo.
Claude Code configuration
claude mcp add --transport http dunning-letters-mcp-zovo https://mcp.zovo.one/mcp/dunning-letters

Codex

Run this once. Codex stores MCP servers in ~/.codex/config.toml (or .codex/config.toml in a trusted project).
Codex configuration
codex mcp add dunning-letters-mcp-zovo --url https://mcp.zovo.one/mcp/dunning-letters

Cursor

Merge this server into .cursor/mcp.json in your project, then enable dunning-letters-mcp-zovo in your MCP settings.
Cursor configuration
{
  "mcpServers": {
    "dunning-letters-mcp-zovo": {
      "url": "https://mcp.zovo.one/mcp/dunning-letters"
    }
  }
}

Cline

Merge this into cline_mcp_settings.json (Cline → MCP Servers → Configure).
Cline configuration
{
  "mcpServers": {
    "dunning-letters-mcp-zovo": {
      "type": "streamableHttp",
      "url": "https://mcp.zovo.one/mcp/dunning-letters",
      "disabled": false
    }
  }
}

VS Code

Merge this server into .vscode/mcp.json. Use MCP: List Servers to start dunning-letters-mcp-zovo and inspect its tools.
VS Code configuration
{
  "servers": {
    "dunning-letters-mcp-zovo": {
      "type": "http",
      "url": "https://mcp.zovo.one/mcp/dunning-letters"
    }
  }
}

Gemini CLI

Run this once. It writes .gemini/settings.json in the current project; pass --scope user for ~/.gemini/settings.json.
Gemini CLI configuration
gemini mcp add --transport http dunning-letters-mcp-zovo https://mcp.zovo.one/mcp/dunning-letters

Claude Desktop

Open Claude Settings > Connectors > Add custom connector, enter this server URL and enable it for the conversation. This is a manual remote-connector handoff, not a desktop JSON configuration.
Claude Desktop configuration
https://mcp.zovo.one/mcp/dunning-letters

Windsurf

Merge this into ~/.codeium/windsurf/mcp_config.json, then refresh MCP in Cascade. Windsurf remote servers use serverUrl, not url.
Windsurf configuration
{
  "mcpServers": {
    "dunning-letters-mcp-zovo": {
      "serverUrl": "https://mcp.zovo.one/mcp/dunning-letters"
    }
  }
}

Let your agent find its tools

Find servers like theluckystrike Dunning Letters MCP from your agent. Add Koskamo once to search the index for endpoints, access requirements, and client setup. Public discovery needs no key.