Numvo
Phone number intelligence and spam-risk detection built with a reusable Python orchestration layer and MCP.
Architecture
Client / MCP Host
↓
MCP adapter
↓
Numvo service
↓
┌──────────────────────┐
│ PhoneNumbersProvider │ metadata / validity
│ FTCComplaintProvider │ complaint reputation
│ IPQSProvider │ fraud / abuse reputation
└──────────────────────┘
↓
Normalize → aggregate → cross-validate → score → explain
What Numvo uses today
Phone metadata
phonenumbers provides number validity, region, carrier information when available, and number type. Metadata alone never makes a number spam.
FTC complaint reputation
Numvo can ingest the FTC Do Not Call complaint CSV data into a local SQLite index. Lookups are then performed by exact phone number without downloading complaint data during every request.
The FTC data is consumer-submitted complaint evidence. Numvo treats it as a signal, not absolute proof that a number is malicious.
IPQS reputation
If IPQS_API_KEY is configured, Numvo queries IPQualityScore for an independent reputation signal including fraud score, recent abuse, risky/spammer flags, and selected phone attributes.
Set the key before starting the MCP server:
export IPQS_API_KEY="your-key"
# Windows PowerShell:
# $env:IPQS_API_KEY="your-key"
The key is read from the environment and should not be committed to the repository.
Spam scoring
FTC complaint scoring considers:
- total complaint count
- complaints in the last 30 and 90 days
- robocall ratio
- whether complaints span multiple dates
IPQS contributes its fraud score plus risky, spammer, and recent-abuse signals.
When two independent reputation providers both produce strong evidence, Numvo applies an agreement boost. This makes multi-source confirmation stronger than a single provider result.
Risk labels are:
0-24 LOW
25-49 SUSPICIOUS
50-74 HIGH
75-100 VERY_HIGH
Confidence and explanations
Every Numvo result separates risk from confidence.
spam_scoreanswers: how suspicious does the available evidence look?confidence_scoreanswers: how much independent reputation evidence supports that conclusion?
Confidence labels are:
0-19 VERY_LOW
20-49 LOW
50-79 MEDIUM
80-100 HIGH
The result also includes human-readable reasons, for example:
FTC complaint history: 31 reports
12 FTC complaints in the last 30 days
84% of FTC reports were robocall-related
IPQS fraud score: 94/100
IPQS identifies the number as a spammer
IPQS reports recent abuse activity
Two independent reputation sources show strong risk signals
This is intentionally explainable: a high risk score with very low confidence should be treated differently from a high risk score confirmed by multiple independent sources.
Development
python -m venv .venv
source .venv/bin/activate # Windows: .venv\\Scripts\\activate
pip install -e ".[dev]"
pytest
Automatic FTC refresh
Numvo can now check recent FTC daily complaint files automatically and ingest any published rows into the local SQLite index.
Refresh the most recent 7 calendar days:
python scripts/refresh_ftc.py
Or choose a wider window:
python scripts/refresh_ftc.py --days 30
Numvo checks each date in the requested window. If the FTC has no file for a date, such as a weekend or non-published day, it records not_published and continues.
Downloaded files are cached under:
data/ftc_daily/
The SQLite index is stored at:
data/ftc_complaints.sqlite3
The refresh is safe to rerun: downloaded CSVs are reused and INSERT OR IGNORE prevents identical complaint rows from being duplicated.
You can still ingest a local FTC CSV manually:
python scripts/ingest_ftc_csv.py path/to/complaints.csv
MCP tools
The server exposes:
check_phone_number(phone_number)
normalize_number(phone_number)
check_phone_number() combines phone metadata, locally indexed FTC complaint evidence, and IPQS reputation when configured, then returns risk, confidence, reasons, and raw provider signals.
Status
Early development. Numvo now supports multi-source spam-risk cross-validation, explicit evidence confidence, human-readable explanations, and automatic FTC complaint-data refresh.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file numvo-0.1.0.tar.gz.
File metadata
- Download URL: numvo-0.1.0.tar.gz
- Upload date:
- Size: 12.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f7b50cc96c9d9ea78d4603be8c967f8a648373e1a3d8eb66ff0a6bdac8159aaa
|
|
| MD5 |
b86e4cb1315a4c08d19744ebfe5907dc
|
|
| BLAKE2b-256 |
e714671c5f2f42be1c483d7253dec4de580f5f13bbef5ec36d5d7f94f1e1b6b1
|
Provenance
The following attestation bundles were made for numvo-0.1.0.tar.gz:
Publisher:
release.yml on karthik1029/Numvo
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
numvo-0.1.0.tar.gz -
Subject digest:
f7b50cc96c9d9ea78d4603be8c967f8a648373e1a3d8eb66ff0a6bdac8159aaa - Sigstore transparency entry: 2734379513
- Sigstore integration time:
-
Permalink:
karthik1029/Numvo@15e19bc1c3d6973da48ee7b023c3a0a1d417213e -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/karthik1029
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@15e19bc1c3d6973da48ee7b023c3a0a1d417213e -
Trigger Event:
release
-
Statement type:
File details
Details for the file numvo-0.1.0-py3-none-any.whl.
File metadata
- Download URL: numvo-0.1.0-py3-none-any.whl
- Upload date:
- Size: 13.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9470b6262ef298c433b26abdf854dfba9f35b5b540a2a69d4b035ee02584be6a
|
|
| MD5 |
57e871f5346eda127635a5e00d348b35
|
|
| BLAKE2b-256 |
6b035a3b61dc67a744c9f611af2e31c25f66dda65fab81506810d67d44068c79
|
Provenance
The following attestation bundles were made for numvo-0.1.0-py3-none-any.whl:
Publisher:
release.yml on karthik1029/Numvo
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
numvo-0.1.0-py3-none-any.whl -
Subject digest:
9470b6262ef298c433b26abdf854dfba9f35b5b540a2a69d4b035ee02584be6a - Sigstore transparency entry: 2734380571
- Sigstore integration time:
-
Permalink:
karthik1029/Numvo@15e19bc1c3d6973da48ee7b023c3a0a1d417213e -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/karthik1029
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@15e19bc1c3d6973da48ee7b023c3a0a1d417213e -
Trigger Event:
release
-
Statement type: