freelancer-payment-protection

MCP server wrapping the fpp CLI for freelancer client payment-risk checks.

Documentation


Bad Cop CRM

Freelancer Payment Protection: AI-Native Collection Engine

npm version PyPI version last commit coverage 70%+ enforced CodeQL enabled License: MIT

Full tech stack badges

Python 3.12 FastAPI 0.111 Next.js 14 App Router TypeScript 5.4 Turborepo monorepo Claude Sonnet 4.6 AI core Supabase PostgreSQL + RLS Celery + Redis workers Framer Motion animations Row Level Security on all tables


73 million freelancers. 71% report late payment. $50B+ in unpaid invoices every year.
The gap: every invoicing tool stops at "sent." None of them handle what comes next.
We built the bad cop so freelancers don't have to be.


freelancer-payment-protection-cli: logging in and running the first command against a live workspace

Built by Rudrendu Paul & Sourav Nandy   ·   Developed with Claude Code   ·   Full-stack product shipped in 15 days using 6 parallel AI sub-agents


InstallThe GapWhat We BuiltWhy It's StickyAI EngineArchitectureQuick Start


Install

The fpp CLI is the fastest way to try this against your own data:

pip install freelancer-payment-protection-cli
fpp login
fpp invoice list --status overdue

Full command reference: Command-Line Interface. To self-host the whole product (Next.js dashboard + FastAPI backend), see Quick Start.


The Gap

FreshBooks handles invoicing. HoneyBook handles proposals. HubSpot handles CRM. None of them handle collection.

When a client goes silent after delivery, freelancers are left with a choice: be "difficult" and chase. Or be professional and absorb the loss. That double bind is the entire product.

What exists today:                    Freelancer Payment Protection Solution:
──────────────────                    ───────────────────────────────────────
Invoice sent ✓                        Invoice sent ✓
Payment expected...                   Payment expected...
[silence]                             → Day 7:  AI Polite Reminder (tone-calibrated)
[more silence]                        → Day 14: AI Firm Notice (cites contract terms)
"Hey, just following up..."           → Day 19: AI Final Warning (deadline set)
[ignored]                             → Day 26: Jurisdiction-aware Demand Letter PDF
[write it off]                        → Day 33: Small claims prep + evidence export

No tool on the market combines all five: AI-drafted legal documents + automated escalation sequences + evidence capture + client risk scoring + invoice integrations. That combination is what's new.


What We Built

An AI-native payment protection SaaS with a five-stage escalation engine, jurisdiction-aware legal document generation, real-time client risk scoring, and a court-ready evidence locker. The product acts as an automated third party. So the freelancer stays the professional.

Five capabilities no single competitor has:

CapabilityHow It Works
AI Escalation EngineFive-stage pipeline. Stage-calibrated tone. Minimum wait times enforced at engine level. Not bypassable via direct API call.
Legal Demand LettersOur AI engine drafts jurisdiction-aware demand letters (CA, NY, TX, UK, Ontario). Streams to the UI in real time with a typewriter effect.
Client Risk Scoring0–100 score across 7 weighted factors. Structured JSON output with full factor breakdown and AI reasoning. Not just a number.
Evidence LockerDrag-and-drop upload. Supabase Storage with signed URLs. One-click court-ready ZIP export.
Invoice SyncFreshBooks, QuickBooks, and Wave OAuth integrations. Background workers sync on webhook + schedule.

Why It's Sticky

This is not a tool people use once. It earns a place in the daily workflow:

Habit LoopMechanism
Daily pullUrgency banner: "3 invoices need your attention today." Personalized every morning.
Action before leaving"Today's Focus," the top 3 urgent actions with one-click CTAs. Leaves no reason to defer.
Payment celebrationConfetti on payment received. Recovery rate updates live. Positive reinforcement loop.
AI confidence visibleEvery email draft shows its confidence score + visual bar. Builds trust, creates engagement.
Pipeline clarityKanban board makes collection feel manageable. 5 columns. Total amount at stake per stage.
Activity feed"Freelancer Payment Protection sent Final Warning to Acme Corp for $12,500." Keeps users informed without checking manually.
Risk revealRisk score counts from 0 → final number with color shift on client detail. Creates a moment.
Escalation learningEach stage sounds noticeably different. Users learn the system, trust it, rely on it.

Retention prediction: Any freelancer who recovers one invoice through Freelancer Payment Protection becomes a retained user. The first win is the conversion event.


Why This Exists

Late payment is a widespread problem for freelancers, and most invoicing tools (FreshBooks, HoneyBook) stop at sending the invoice. They don't help once a client goes quiet. This project automates the escalation conversation that would otherwise fall on the freelancer.

The AI generation quality needed for jurisdiction-aware legal documents (not just template filling) is a recent capability. Reliable structured output at this consistency level wasn't practical much before 2025.


The Escalation Pipeline

Five stages. Minimum wait times enforced at the service layer. Not the UI, not suggestions. A direct API call cannot skip a stage window. The scheduler checks daily.

Invoice Overdue
     │
     ▼ Day 1
 ┌─────────────────┐
 │  Polite Reminder │  Warm. "Just checking in." Invoice summary. No pressure.
 │  (wait: 7 days)  │
 └────────┬────────┘
          │ Day 8
          ▼
 ┌─────────────────┐
 │   Firm Notice   │  Direct. References contract terms. 7-day deadline set.
 │  (wait: 7 days)  │
 └────────┬────────┘
          │ Day 15
          ▼
 ┌─────────────────┐
 │  Final Warning  │  Authoritative. Final notice before formal process begins.
 │  (wait: 5 days)  │
 └────────┬────────┘
          │ Day 22
          ▼
 ┌─────────────────┐
 │  Legal Demand   │  Jurisdiction-aware PDF. Streaming. Cites statute.
 │  (wait: 7 days)  │
 └────────┬────────┘
          │ Day 30+
          ▼
 ┌─────────────────┐
 │  Legal Action   │  Small claims prep. Full evidence export. Court-ready.
 └─────────────────┘

Every email is generated by our AI engine with a confidence score. The freelancer sees the score before approving. Nothing sends without human review.


AI Under the Hood

Our AI engine isn't a feature here. The product doesn't function without it.

1. Legal Demand Letter Generation

Our AI engine drafts jurisdiction-specific demand letters for California, New York, Texas, England & Wales, and Ontario. Each letter:

  • References the exact invoice number, amount, and due date
  • Lists previous contact attempts chronologically
  • Sets a 7-business-day final payment deadline
  • Specifies consequences: credit reporting, small claims, collections referral
  • Cites relevant consumer protection statutes by jurisdiction

The streaming bridge: The Anthropic Python SDK is synchronous. FastAPI is async. We bridge them with a threading.Thread pushing SSE chunks into a queue.Queue, then asyncio.run_in_executor pulls on the async side. The event loop never blocks. The typewriter effect is smooth.

Every generated document displays this disclaimer, enforced in the system prompt, verified by the legal-ai-agent, non-negotiable:

2. Client Risk Scoring

Seven weighted factors → 0–100 score → structured JSON with full reasoning:

{
  "score": 82,
  "level": "critical",
  "factors": [
    { "name": "Industry payment culture", "weight": 0.18, "impact": "negative", "description": "..." },
    { "name": "Historical delay average", "weight": 0.22, "impact": "negative", "description": "..." },
    ...
  ],
  "reasoning": "TechVentures Inc shows three compounding risk signals: ..."
}

The UI renders the full factor breakdown with animated progress bars and the AI's reasoning verbatim. A score without reasoning is noise. The freelancer sees why.

ScoreLevelAction
0–25🟢 LowStandard payment terms
26–50🟡 MediumRequest 25–50% deposit
51–75🟠 High50% upfront. Non-negotiable
76–100🔴 CriticalFull payment before work begins

3. Escalation Email Generator

Stage-calibrated structured output per escalation:

{
    "subject": str,
    "body": str,
    "tone": Literal["warm", "direct", "authoritative", "formal"],
    "confidence_score": float,  # 0.0–1.0, shown in UI with progress bar
    "key_phrases": list[str],   # phrases that signal the stage escalation
}

The confidence score and a visual bar appear in the email preview dialog. Freelancers see how certain the model is about the tone calibration before they hit send. If confidence is low, they regenerate.


MCP-Powered Development

MCP servers were used throughout development, not as a demo but as the actual development infrastructure.

MCP ServerWhat It Did
Supabase MCPOur development environment queried the live schema before writing a single query. Migrations were validated against real data. RLS policies were checked in plain English.
GitHub MCPPR creation, diff review, CI status, all without leaving the terminal. Every merge went through our AI security checklist first.
Gmail MCPEscalation email flows tested against real threads. The evidence scraper validated against actual email structures, not fabricated fixtures.
DocuSign MCPDigital signature integration for demand letters wired with live API validation.
QuickBooks MCPReal invoice data during integration development. No mocked responses that diverge from production behavior.
Sequential Thinking MCPUsed specifically for risk scoring. Forces step-by-step reasoning through all 7 risk factors before a score is produced. Prevents hallucinated shortcuts.

The principle: every external API was validated against the live service before it shipped. This is what separates "code that looks correct" from "code that behaves correctly in production."


Sub-Agent Architecture

Six specialized agents ran in parallel during development. Strict file-system boundaries meant zero merge conflicts when the legal AI layer and the frontend evolved simultaneously.

.claude/agents/
├── legal-ai-agent.md       # Claude prompts, demand letter gen, disclaimer enforcement
│                           # Boundary: packages/legal_ai/ only
│
├── escalation-agent.md     # Timing engine, tone calibration, stage progression
│                           # Boundary: apps/api/app/services/escalation_service.py
│
├── integration-agent.md    # FreshBooks / QuickBooks / Wave OAuth, token refresh, retry
│                           # Boundary: packages/integrations/ only
│
├── risk-scoring-agent.md   # Risk model design, 7 factors, thresholds, synthetic test data
│                           # Boundary: apps/api/app/services/risk_service.py
│
├── evidence-locker-agent.md # Evidence capture, Supabase Storage, signed URLs, court ZIP
│                           # Boundary: apps/api/app/routers/evidence.py
│
└── test-agent.md           # pytest unit/integration, Playwright E2E, adversarial legal tests
                            # Boundary: **/tests/ only

Custom commands that encode team process as executable slash commands:

/new-escalation-template <stage>   # Scaffold email template + pytest test in one shot
/generate-demand-letter <id>       # Generate demand letter for a specific invoice
/review-pr                         # Security + performance + MLP lovability checklist

Architecture

System Diagram

graph TB
    subgraph "Frontend: Next.js 14"
        A[App Router Pages]
        B[TanStack Query Cache]
        C[Framer Motion UI]
        D[Supabase Auth Client]
    end

    subgraph "Backend: FastAPI Python 3.12"
        E[FastAPI App Factory]
        F[JWT Middleware]
        G[slowapi Rate Limiter]
        H[Routers: 8 domains]
        I[Services: business logic only]
    end

    subgraph "AI: Claude Sonnet 4.6"
        J[packages/legal_ai/client.py]
        K[Demand Letter: streaming SSE]
        L[Escalation Email: structured]
        M[Risk Scorer: JSON output]
        N[Dispute Summary]
    end

    subgraph "Document Pipeline"
        O[python-docx]
        P[WeasyPrint PDF]
    end

    subgraph "Workers: Celery + Redis"
        Q[Invoice Sync]
        R[Escalation Scheduler]
        S[Evidence Scraper]
    end

    subgraph "Data Layer"
        T[(Supabase PostgreSQL + RLS)]
        U[Supabase Storage]
        V[(Redis Queue)]
        W[(SQLite Dev DB)]
    end

    subgraph "External Integrations"
        X[FreshBooks]
        Y[QuickBooks]
        Z[Wave]
        AA[Resend Email]
    end

    A --> E
    D --> T
    B --> E
    E --> F --> G --> H --> I
    I --> J
    J --> K --> O --> P
    J --> L --> AA
    J --> M
    J --> N
    I --> T & U
    Q --> X & Y & Z --> T
    R --> AA & T
    S --> U & T
    Q & R & S --> V

Request Flow: Overdue Invoice to Sent Escalation

sequenceDiagram
    participant FB as FreshBooks
    participant W as Celery Worker
    participant DB as Supabase
    participant AI as Claude API
    participant Email as Resend
    participant FE as Dashboard

    FB->>W: Webhook: invoice.overdue
    W->>DB: Upsert invoice + compute days_past_due
    W->>AI: Generate escalation (stage: polite_reminder)
    Note over AI: Structured output: subject, body,<br/>tone, confidence_score, key_phrases
    AI-->>W: EscalationEvent JSON
    W->>DB: Store EscalationEvent (sentAt = null)
    W->>Email: Send via Resend
    Email-->>W: 200 OK + messageId
    W->>DB: Update sentAt + nextEscalationDate
    FE->>DB: Poll via TanStack Query
    DB-->>FE: Updated invoice + escalation status
    Note over FE: Activity feed: "Reminder sent ✓<br/>Next action in 7 days"

Engineering Decisions

Every architectural choice has a reason. Here are the non-obvious ones:

Why Python for the backend, not Node? Legal document generation requires python-docx and WeasyPrint. The only libraries that produce court-quality PDFs with real typographic control. The Anthropic Python SDK is the reference implementation. The Python ecosystem is also significantly stronger for anything legally adjacent (NLTK, spaCy for contract analysis in V3).

Why enforce escalation wait times at the service layer? A UI-only constraint can be bypassed with a direct API call. The minimum wait window check lives in escalation_service.py. So the rule applies regardless of how escalation is triggered: dashboard button, direct API call, or background worker. Trust the service contract, not the interface.

Why centralize all Claude calls in one file? packages/legal_ai/client.py is the only place the Anthropic SDK is imported. A rule checked in every PR. Logging, retries, timeout handling, model version pinning, and the async/sync bridge all live there. When we upgrade from Sonnet 4.6, we change one file.

Why Pydantic Settings with fail-fast validation? settings = Settings() executes at module import time. If ANTHROPIC_API_KEY is absent, the application raises ValidationError before serving a single request. No silent degradation. No "AI features just stopped working." Fail loud, fail early.

Why SQLite for dev? No Docker, no install, no credentials. Anyone evaluating this repo is running it in five minutes. SQLAlchemy's dialect abstraction means the ORM layer is identical across SQLite and Postgres. Only the connection string changes.

Why Turborepo? TypeScript (frontend) and Python (backend) build pipelines run in parallel with a shared cache. pnpm turbo test runs everything. Clear package boundaries (packages/legal_ai, packages/types, packages/integrations), each with one owner and one job.


Tech Stack Reference

Frontend

LibraryVersionRole
Next.js14App Router, Server Components, BFF routes
TypeScript5.4Strict mode, no any. Enforced by CI
Tailwind CSS3.4Utility-first styling, custom design tokens
shadcn/uilatestAccessible component primitives
Framer Motion11All animations: stagger, spring, typewriter, confetti
TanStack Query5Server state, optimistic updates, cache invalidation
Zod3Runtime validation at API boundaries
Sonner1Toast notifications with personality copy

Backend

LibraryVersionRole
Python3.12Type annotations throughout
FastAPI0.111Async API, OpenAPI auto-generation
SQLAlchemy2ORM, dialect-agnostic (SQLite ↔ Postgres)
Alembic1.13Schema migrations. Never direct edits
Pydantic2Request/response validation, Settings
python-docx1.1Word document generation
WeasyPrint62PDF rendering with CSS
slowapi0.1Rate limiting (100/min global, 10/min AI routes)
Celery5Background workers

Infrastructure

LayerChoiceWhy
AuthSupabase JWT + httpOnly cookies + PKCEPKCE blocks auth code interception; httpOnly blocks XSS token theft
DatabaseSupabase PostgreSQLRow Level Security enforces workspace isolation at DB layer, not app layer
StorageSupabase StorageSigned URLs (1hr expiry), no public access for evidence files
QueueRedis + CeleryReliable job delivery; escalation scheduler is time-sensitive
EmailResend + React EmailTemplates are React components. Testable, version-controlled
MonorepoTurborepo + pnpmParallel builds, shared cache, cross-language workspace
CIGitHub Actionslint → typecheck → test → security audit → PR gates
SASTCodeQLPython + TypeScript, every PR

Security

Production-grade from day one. Not added at the end.

ControlImplementation
AuthenticationSupabase JWT + httpOnly cookies + PKCE flow
AuthorizationRLS on every table. Workspace isolation at DB, not app layer
SecretsPydantic SecretStr. App refuses to start if any required var is missing
Input validationPydantic v2 on every endpoint. Rejection before business logic
Rate limiting100 req/min global; 10/min on legal routes (AI is expensive)
CORSAllowlist-based. No wildcard in production
SQL injectionSQLAlchemy ORM only. Zero raw SQL
XSSReact escaping + strict Content Security Policy
Evidence accessSigned URLs; 1-hour expiry, no public buckets
Dependency auditsafety + pip-audit. PRs blocked on findings
SASTCodeQL (Python + TypeScript) on every PR

Repository Structure

freelancer-payment-protection/
│
├── apps/
│   ├── web/                          # Next.js 14 App Router (TypeScript, strict)
│   │   └── src/
│   │       ├── app/
│   │       │   ├── dashboard/        # Urgency banner · 6 metric cards · Today's Focus · Activity Feed
│   │       │   ├── clients/          # Risk-sorted table · [id] detail with animated risk reveal
│   │       │   ├── invoices/         # Filter bar · [id] timeline · drag-and-drop evidence locker
│   │       │   ├── escalations/      # 5-column kanban · amount-at-stake per stage
│   │       │   └── legal/            # Streaming demand letter generator (SSE typewriter)
│   │       │
│   │       └── components/
│   │           ├── layout/           # SidebarLayout. Nav badges, recovery widget, keyboard hints
│   │           ├── dashboard/        # MetricCard · ActivityFeed · TodaysFocus · RiskDistributionChart
│   │           ├── escalations/      # EscalationCard (urgency ring, flame) · StageColumn (amount)
│   │           ├── shared/           # EmptyState · LoadingSkeleton (shimmer) · RiskBadge · StatusBadge
│   │           └── ui/               # shadcn/ui primitives
│   │
│   ├── api/                          # FastAPI backend. Python 3.12
│   │   └── app/
│   │       ├── main.py               # App factory + lifespan hooks
│   │       ├── config.py             # Pydantic Settings. Fail-fast validation
│   │       ├── database.py           # SQLAlchemy engine + session factory
│   │       ├── routers/              # clients · invoices · escalations · legal_docs
│   │       │                         # evidence · risk_scoring · analytics · health
│   │       ├── services/             # ai_service · escalation_service (timing engine)
│   │       │                         # doc_gen_service · risk_service
│   │       ├── middleware/           # JWT auth · rate_limit · CORS
│   │       ├── models/               # SQLAlchemy ORM (client, invoice, escalation, evidence, workspace)
│   │       └── schemas/              # Pydantic request/response schemas
│   │
│   └── workers/                      # Celery background workers
│       └── tasks/                    # invoice_sync · escalation_scheduler · evidence_scraper
│
├── packages/
│   ├── legal_ai/                     # The AI layer. Centralized, auditable
│   │   ├── client.py                 # ONLY place Anthropic SDK is called. Enforced in CI
│   │   └── prompts/
│   │       ├── demand_letter.py      # Jurisdiction-aware prompts (CA, NY, TX, UK, Ontario)
│   │       ├── escalation_sequence.py # Stage-calibrated tone prompts
│   │       ├── risk_scoring.py       # 7-factor structured JSON output
│   │       └── dispute_summary.py    # Evidence synthesis
│   │
│   ├── db/
│   │   ├── migrations/versions/      # Alembic. All schema changes live here
│   │   │   ├── 001_initial_schema.py
│   │   │   └── 002_rls_policies.sql  # RLS on every table
│   │   ├── models/                   # SQLAlchemy models (source of truth)
│   │   └── seeds/                    # 50 clients, 50 invoices, 20 escalations. No creds needed
│   │
│   ├── integrations/                 # FreshBooks, QuickBooks, Wave OAuth connectors
│   └── types/                        # Shared TypeScript types. Strict, no `any`
│
├── .claude/
│   ├── agents/                       # 6 domain-bounded sub-agents with file-system boundaries
│   └── commands/                     # Executable slash commands encoding team process
│
├── legal-templates/                  # Jurisdiction base templates (CA-Ontario, UK, US-CA, US-NY)
├── turbo.json                        # Parallel pipeline: build, test, lint
└── .github/workflows/                # CI: lint → typecheck → pytest → CodeQL → security audit

Quick Start

No external services needed to seed and query data through the API/CLI. Viewing the web dashboard itself requires a (free-tier) Supabase project for login — see the note below.

Prerequisites: Node.js 20+ · pnpm 9.0.0 (see corepack note below) · Python 3.12.x (3.13/3.14 not yet supported — see note below)

[!WARNING] Requires Python 3.12.x specifically. 3.13 and 3.14 are not yet supported.

git clone https://github.com/RudrenduPaul/freelancer-payment-protection.git
cd freelancer-payment-protection

# If your global pnpm doesn't already resolve to 9.0.0 under corepack, pin it first:
# corepack prepare pnpm@9.0.0 --activate

# Monorepo dependencies
pnpm install

# Env files (placeholder values work for the API/CLI seed-data path;
# apps/web needs a REAL Supabase URL + anon key to log in, see note below)
cp apps/api/.env.example apps/api/.env
cp apps/web/.env.example apps/web/.env.local

# Python setup — run from the repo root, not apps/api
pip install -r apps/api/requirements.txt
python -m alembic -c packages/db/migrations/alembic.ini upgrade head
python scripts/seed_dev.py

# Start frontend + API in parallel
pnpm dev
ServiceURL
Dashboardhttp://localhost:3000
API + OpenAPI docshttp://localhost:8000/docs

8 mock clients · 16 invoices · pre-generated escalation events · evidence items, all queryable via the API/CLI without any external service once seeded.

[!WARNING] Web dashboard login requires a real (free-tier is fine) Supabase project: apps/api/app/middleware/auth.py validates a Supabase-issued JWT on every protected route with no local bypass, and apps/web/.env.example's placeholder values will not let you log in. Put your project's URL/anon key in apps/web/.env.local and apps/api/.env to use the dashboard; the seeded data is otherwise fully reachable through the API/CLI with the placeholder env files as-is.

[!NOTE] AI features (demand letters, risk scoring, escalation drafts) require ANTHROPIC_API_KEY in apps/api/.env. Variable name is in .env.example. Never commit real keys.


API Reference

Interactive OpenAPI at http://localhost:8000/docs. Key endpoints:

GET  /api/v1/analytics/overview          # Dashboard totals
GET  /api/v1/clients                     # List clients
POST /api/v1/escalations/{id}/draft      # AI-draft next escalation email (preview)
POST /api/v1/legal/demand-letter/stream  # Generate + stream demand letter (SSE)
POST /api/v1/risk/score                  # AI risk score for a client
Full endpoint surface (verified against the router source directly)
GET    /health                                Liveness probe
GET    /health/ready                          Readiness (DB + Redis)

GET    /api/v1/clients                        List
POST   /api/v1/clients                        Create
GET    /api/v1/clients/{client_id}            Detail
PUT    /api/v1/clients/{client_id}            Update
DELETE /api/v1/clients/{client_id}            Delete

GET    /api/v1/invoices                       List
POST   /api/v1/invoices                       Create (manual)
GET    /api/v1/invoices/{invoice_id}          Detail
PATCH  /api/v1/invoices/{invoice_id}/status   Update status

GET    /api/v1/escalations                    Active escalations
POST   /api/v1/escalations/{invoice_id}/draft    AI-draft next escalation email
GET    /api/v1/escalations/{invoice_id}/history  Full history

POST   /api/v1/legal/demand-letter            Generate demand letter
POST   /api/v1/legal/demand-letter/stream     Generate + stream (SSE)

GET    /api/v1/evidence/{invoice_id}          Evidence items
POST   /api/v1/evidence/{invoice_id}/upload   Manual upload
DELETE /api/v1/evidence/{item_id}             Remove

POST   /api/v1/risk/score                     AI risk score, structured JSON

GET    /api/v1/analytics/overview             Dashboard totals

Command-Line Interface

A standalone freelancer-payment-protection-cli package (packages/cli/) wraps the clients, invoices, escalations, and risk-scoring endpoints above for terminal and agent/scripting use, with a --json flag on every data-returning command. See packages/cli/README.md for installation, the full command reference, and a login/auth walkthrough.

pip install freelancer-payment-protection-cli
fpp login
fpp invoice list --status overdue
fpp client risk <client-id>
freelancer-payment-protection-cli: filtering overdue invoices, scoring a client, and checking escalation status

Every data-returning command also takes --json for structured output an agent or script can parse directly:

freelancer-payment-protection-cli: running fpp commands with --json to get structured, machine-parseable output

MCP Server

freelancer-payment-protection-cli ships a Model Context Protocol (MCP) server, so an agent (Claude Desktop, Claude Code, or any other MCP client) can call the same commands above (invoice list, client risk, escalation status, ...) as tool calls instead of shelling out to the CLI directly.

Install:

pip install "freelancer-payment-protection-cli[mcp]"

Claude Desktop config (claude_desktop_config.json):

{
  "mcpServers": {
    "freelancer-payment-protection": {
      "command": "fpp-mcp"
    }
  }
}

The server exposes one tool, run, that shells out to the installed fpp binary with the given argument list and returns its output as structured JSON when possible — every fpp subcommand is reachable through it, not just a hand-picked subset. Example call: run(args=["client", "risk", "<client-id>", "--json"]) returns the same 0-100 risk score, factor breakdown, and AI reasoning that fpp client risk <client-id> --json prints to a terminal.


Running Tests

# Backend. Pytest + coverage
cd apps/api && pytest --cov=app --cov-report=term-missing

# Frontend. Vitest
pnpm --filter web test

# E2E. Playwright
pnpm --filter web test:e2e

# Full pipeline
pnpm turbo test

Coverage gates (enforced in CI, PRs blocked on failure):

  • 70% minimum line coverage on all new code
  • 90%+ on risk scoring, escalation service, and document generation
  • Every new route: happy path + auth failure + validation error
  • Zero live external API calls in test suite. All mocked

Pricing

PlanMonthlyClientsWhat's Included
Solo$2910Escalation sequence · 3 AI demand letters/mo · Manual evidence upload
Pro$59UnlimitedUnlimited AI documents · Evidence locker + court export · Full risk scoring · All integrations
Agency$99UnlimitedMulti-user workspace · White-label client portal · API access · Priority support

20% discount on annual billing.


What No Competitor Does

CapabilitySpreadsheetsFreshBooksHoneyBookHubSpotFreelancer Payment Protection
AI escalation (tone-calibrated)Reminders onlyBasicManualStage-aware + confidence-scored
Jurisdiction-aware demand lettersCA / NY / TX / UK / Ontario (PDF)
Client risk scoring (0–100)7 factors + AI reasoning
Evidence locker + court exportAuto-captured + ZIP download
Streaming AI generationSSE typewriter, real-time
Invoice sync integrationsNativeNativeFreshBooks / QuickBooks / Wave
Min wait times at engine levelN/AN/AN/AN/AService layer. API-call-proof

License

MIT. See LICENSE for full terms.

Contact: github.com/RudrenduPaul


Built by Rudrendu Paul and Sourav Nandy · Developed with Claude Code


If this approach to AI-native development is useful to you, star the repo.
It helps other developers and founders find the methodology.