freelancer-payment-protection

freelancer-payment-protection

MCP server wrapping the fpp CLI as a single generic run tool for freelancer client payment-risk checks.

Category
访问服务器

README

<!-- mcp-name: io.github.RudrenduPaul/freelancer-payment-protection --> <div align="center">

<br/>

<img src="https://img.shields.io/badge/-%F0%9F%9B%A1%EF%B8%8F%20BAD%20COP%20CRM-1a1a2e?style=for-the-badge&logoColor=white" height="40" alt="Bad Cop CRM" />

<h2>Freelancer Payment Protection: AI-Native Collection Engine</h2>

<!-- Badge cluster, capped at 6. Full stack badges live in the details block below. --> <p> <img src="https://img.shields.io/npm/v/freelancer-payment-protection-cli?style=flat&logo=npm&label=npm" alt="npm version" /> <img src="https://img.shields.io/pypi/v/freelancer-payment-protection-cli?style=flat&logo=pypi&logoColor=white&label=PyPI" alt="PyPI version" /> <img src="https://img.shields.io/github/last-commit/RudrenduPaul/freelancer-payment-protection?style=flat&label=last+commit" alt="last commit" /> <img src="https://img.shields.io/badge/Coverage-70%25%2B_enforced-22c55e?style=flat" alt="coverage 70%+ enforced" /> <img src="https://img.shields.io/badge/CodeQL-Enabled-22c55e?style=flat" alt="CodeQL enabled" /> <a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT" /></a> </p>

<details> <summary>Full tech stack badges</summary> <br/>

<p> <img src="https://img.shields.io/badge/Python-3.12-3776AB?style=flat&logo=python&logoColor=white" alt="Python 3.12" /> <img src="https://img.shields.io/badge/FastAPI-0.111-009688?style=flat&logo=fastapi&logoColor=white" alt="FastAPI 0.111" /> <img src="https://img.shields.io/badge/Next.js-14_App_Router-000000?style=flat&logo=nextdotjs&logoColor=white" alt="Next.js 14 App Router" /> <img src="https://img.shields.io/badge/TypeScript-5.4-3178C6?style=flat&logo=typescript&logoColor=white" alt="TypeScript 5.4" /> <img src="https://img.shields.io/badge/Turborepo-Monorepo-EF4444?style=flat&logo=turborepo&logoColor=white" alt="Turborepo monorepo" /> <img src="https://img.shields.io/badge/Claude_Sonnet_4.6-AI_Core-D4A017?style=flat&logo=anthropic&logoColor=white" alt="Claude Sonnet 4.6 AI core" /> <img src="https://img.shields.io/badge/Supabase-PostgreSQL_%2B_RLS-3ECF8E?style=flat&logo=supabase&logoColor=white" alt="Supabase PostgreSQL + RLS" /> <img src="https://img.shields.io/badge/Celery_%2B_Redis-Workers-37814A?style=flat" alt="Celery + Redis workers" /> <img src="https://img.shields.io/badge/Framer_Motion-Animations-0055FF?style=flat" alt="Framer Motion animations" /> <img src="https://img.shields.io/badge/RLS-All_Tables-6366f1?style=flat" alt="Row Level Security on all tables" /> </p>

</details>

<br/>

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

<br/>

<img src="https://raw.githubusercontent.com/RudrenduPaul/freelancer-payment-protection/main/docs/demo.gif" width="100%" alt="freelancer-payment-protection-cli: logging in and running the first command against a live workspace" />

<br/>

<p> Built by <strong><a href="https://github.com/RudrenduPaul">Rudrendu Paul</a></strong> & <strong><a href="https://github.com/essen-code">Sourav Nandy</strong>   ·   Developed with <a href="https://claude.ai/code">Claude Code</a>   ·   <strong>Full-stack product shipped in 15 days</strong> using 6 parallel AI sub-agents </p>

<br/>

<!-- Navigation --> <table> <tr> <td align="center"><a href="#install"><b>Install</b></a></td> <td align="center"><a href="#the-gap"><b>The Gap</b></a></td> <td align="center"><a href="#what-we-built"><b>What We Built</b></a></td> <td align="center"><a href="#why-its-sticky"><b>Why It's Sticky</b></a></td> <td align="center"><a href="#ai-under-the-hood"><b>AI Engine</b></a></td> <td align="center"><a href="#architecture"><b>Architecture</b></a></td> <td align="center"><a href="#quick-start"><b>Quick Start</b></a></td> </tr> </table>

<br/>

<!-- ═══════════════════════════════════════════════════════════ 📸 SCREENSHOTS. Add these and this README goes to the top ═══════════════════════════════════════════════════════════ Recommended: 1280×800, retina, light mode

  1. /docs/screenshots/01-dashboard.png → Welcome banner with urgency summary + 6 metric cards + Today's Focus + Activity Feed

  2. /docs/screenshots/02-escalation-kanban.png → 5-column kanban with amount-at-stake per column, flame icon on critical cards

  3. /docs/screenshots/04-client-risk.png → Client detail page: risk score counting 0→82, factor breakdown with progress bars, AI reasoning

Uncomment once screenshots are added: --> <!-- <img src="./docs/screenshots/01-dashboard.png" width="100%" alt="Dashboard, urgency-first design" /> -->

</div>


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:

Capability How It Works
AI Escalation Engine Five-stage pipeline. Stage-calibrated tone. Minimum wait times enforced at engine level. Not bypassable via direct API call.
Legal Demand Letters Our 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 Scoring 0–100 score across 7 weighted factors. Structured JSON output with full factor breakdown and AI reasoning. Not just a number.
Evidence Locker Drag-and-drop upload. Supabase Storage with signed URLs. One-click court-ready ZIP export.
Invoice Sync FreshBooks, 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 Loop Mechanism
Daily pull Urgency 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 celebration Confetti on payment received. Recovery rate updates live. Positive reinforcement loop.
AI confidence visible Every email draft shows its confidence score + visual bar. Builds trust, creates engagement.
Pipeline clarity Kanban 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 reveal Risk score counts from 0 → final number with color shift on client detail. Creates a moment.
Escalation learning Each 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.

Score Level Action
0–25 🟢 Low Standard payment terms
26–50 🟡 Medium Request 25–50% deposit
51–75 🟠 High 50% upfront. Non-negotiable
76–100 🔴 Critical Full 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 Server What It Did
Supabase MCP Our 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 MCP PR creation, diff review, CI status, all without leaving the terminal. Every merge went through our AI security checklist first.
Gmail MCP Escalation email flows tested against real threads. The evidence scraper validated against actual email structures, not fabricated fixtures.
DocuSign MCP Digital signature integration for demand letters wired with live API validation.
QuickBooks MCP Real invoice data during integration development. No mocked responses that diverge from production behavior.
Sequential Thinking MCP Used 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

Library Version Role
Next.js 14 App Router, Server Components, BFF routes
TypeScript 5.4 Strict mode, no any. Enforced by CI
Tailwind CSS 3.4 Utility-first styling, custom design tokens
shadcn/ui latest Accessible component primitives
Framer Motion 11 All animations: stagger, spring, typewriter, confetti
TanStack Query 5 Server state, optimistic updates, cache invalidation
Zod 3 Runtime validation at API boundaries
Sonner 1 Toast notifications with personality copy

Backend

Library Version Role
Python 3.12 Type annotations throughout
FastAPI 0.111 Async API, OpenAPI auto-generation
SQLAlchemy 2 ORM, dialect-agnostic (SQLite ↔ Postgres)
Alembic 1.13 Schema migrations. Never direct edits
Pydantic 2 Request/response validation, Settings
python-docx 1.1 Word document generation
WeasyPrint 62 PDF rendering with CSS
slowapi 0.1 Rate limiting (100/min global, 10/min AI routes)
Celery 5 Background workers

Infrastructure

Layer Choice Why
Auth Supabase JWT + httpOnly cookies + PKCE PKCE blocks auth code interception; httpOnly blocks XSS token theft
Database Supabase PostgreSQL Row Level Security enforces workspace isolation at DB layer, not app layer
Storage Supabase Storage Signed URLs (1hr expiry), no public access for evidence files
Queue Redis + Celery Reliable job delivery; escalation scheduler is time-sensitive
Email Resend + React Email Templates are React components. Testable, version-controlled
Monorepo Turborepo + pnpm Parallel builds, shared cache, cross-language workspace
CI GitHub Actions lint → typecheck → test → security audit → PR gates
SAST CodeQL Python + TypeScript, every PR

Security

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

Control Implementation
Authentication Supabase JWT + httpOnly cookies + PKCE flow
Authorization RLS on every table. Workspace isolation at DB, not app layer
Secrets Pydantic SecretStr. App refuses to start if any required var is missing
Input validation Pydantic v2 on every endpoint. Rejection before business logic
Rate limiting 100 req/min global; 10/min on legal routes (AI is expensive)
CORS Allowlist-based. No wildcard in production
SQL injection SQLAlchemy ORM only. Zero raw SQL
XSS React escaping + strict Content Security Policy
Evidence access Signed URLs; 1-hour expiry, no public buckets
Dependency audit safety + pip-audit. PRs blocked on findings
SAST CodeQL (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
Service URL
Dashboard http://localhost:3000
API + OpenAPI docs http://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

<details> <summary>Full endpoint surface (verified against the router source directly)</summary>

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

</details>


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>

<img src="https://raw.githubusercontent.com/RudrenduPaul/freelancer-payment-protection/main/docs/usage.gif" width="100%" alt="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:

<img src="https://raw.githubusercontent.com/RudrenduPaul/freelancer-payment-protection/main/docs/demo-3-json-structured-output.gif" width="100%" alt="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

Plan Monthly Clients What's Included
Solo $29 10 Escalation sequence · 3 AI demand letters/mo · Manual evidence upload
Pro $59 Unlimited Unlimited AI documents · Evidence locker + court export · Full risk scoring · All integrations
Agency $99 Unlimited Multi-user workspace · White-label client portal · API access · Priority support

20% discount on annual billing.


What No Competitor Does

Capability Spreadsheets FreshBooks HoneyBook HubSpot Freelancer Payment Protection
AI escalation (tone-calibrated) Reminders only Basic Manual Stage-aware + confidence-scored
Jurisdiction-aware demand letters CA / NY / TX / UK / Ontario (PDF)
Client risk scoring (0–100) 7 factors + AI reasoning
Evidence locker + court export Auto-captured + ZIP download
Streaming AI generation SSE typewriter, real-time
Invoice sync integrations Native Native FreshBooks / QuickBooks / Wave
Min wait times at engine level N/A N/A N/A N/A Service layer. API-call-proof

License

MIT. See LICENSE for full terms.

Contact: github.com/RudrenduPaul


<div align="center">

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

<br/>

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

</div>

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选