loading…
Search for a command to run...
loading…
Enables AI assistants to send real faxes through the FaxDrop API. Provides safeguards including rate limiting, dry-run mode, and audit logging for secure fax op
Enables AI assistants to send real faxes through the FaxDrop API. Provides safeguards including rate limiting, dry-run mode, and audit logging for secure fax operations.
Send real faxes from any MCP-enabled AI assistant. Wraps the FaxDrop HTTP API.
CI CodeQL Tested with Vitest codecov OpenSSF Scorecard OpenSSF Best Practices Socket Security CodeRabbit Pull Request Reviews
npm version npm downloads Node.js Version MCP MCP Server PRs Welcome
Sponsor on GitHub Patreon Ko-fi
A Model Context Protocol (MCP) server that lets AI assistants (Claude, Cursor, Continue, OpenClaw…) send real faxes through the FaxDrop API.
Faxing is still required by US healthcare, government forms, and a long tail of legal/financial workflows. FaxDrop is a hosted fax service with a clean HTTP API and a free tier (2 faxes/month). This MCP exposes it to LLMs with the safeguards an agent platform actually needs.
You can. But every agent that does ends up re-implementing the same handful of guards. This MCP gives them to you for free:
fs.open(), size enforced continuously while reading.recipientNumber, faxId, id) in clear, blocks the credential set (apiKey / authorization / password / …), and elides every other field with a length marker ([ELIDED:NNN]). Property-tested with fast-check.FAXDROP_MCP_DRY_RUN=true to test prompts without sending; FAXDROP_MCP_AUDIT_LOG=/abs/path for a JSONL trail (mode 0o600).isError with error_type, hint, retry_after.npx -y faxdrop-mcp line in Claude Desktop / Code / Cursor / Continue / OpenClaw.A ~12 KB wrapper that turns a one-week security review into a one-line config change.
npm install -g faxdrop-mcp
Or use directly with npx:
npx faxdrop-mcp
The server reads FAXDROP_API_KEY from the environment. Get your key at faxdrop.com/account (Developer API → Generate Key). Keys look like fd_live_<32 hex>.
Add to ~/Library/Application Support/Claude/claude_desktop_config.json (or ~/.claude.json for Claude Code):
{
"mcpServers": {
"faxdrop": {
"command": "npx",
"args": ["-y", "faxdrop-mcp"],
"env": {
"FAXDROP_API_KEY": "fd_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}
}
}
}
Add to ~/.cursor/mcp.json:
{
"mcpServers": {
"faxdrop": {
"command": "npx",
"args": ["-y", "faxdrop-mcp"],
"env": {
"FAXDROP_API_KEY": "fd_live_..."
}
}
}
}
Add to ~/.openclaw/openclaw.json, then restart the gateway (docker restart openclaw-openclaw-gateway-1 or your equivalent).
faxdrop_send_faxSend a fax. Uploads a local document from the outbox (default ~/FaxOutbox/) to a fax number in international (E.164) format.
Required:
filePath (string, absolute) — PDF, DOCX, JPEG, or PNG, ≤10 MB. Must live inside the outbox.recipientNumber (string) — E.164, e.g. +12125551234. Subject to the 3-layer phone gate (TYPE → COUNTRY → per-number).senderName (string)senderEmail (string)Optional cover-page fields (printed only when includeCover is true):
includeCover (boolean) — free accounts always include a branded cover; paid accounts default to falsecoverNote (string, ≤500) — message bodyrecipientName (≤50), subject (≤200), senderCompany (≤100), senderPhone (validated E.164)Returns: { success, faxId, status, statusUrl }
faxdrop_pair_numberAdd a fax number to the paired whitelist (~/.faxdrop-mcp/paired.json). Only effective when FAXDROP_MCP_NUMBER_GATE=pairing (default). The number must still pass the TYPE and COUNTRY checks (no bypass). Always confirm with the user before pairing — paired numbers can be faxed without further per-number approval.
Required:
recipientNumber (string) — E.164Returns: { paired, country, type }
faxdrop_get_fax_statusCheck the delivery status of a previously sent fax. Terminal statuses (delivered / failed / partial) are cached process-wide (LRU 100 entries, whitelist-sliced) — re-polling a finished fax short-circuits with a _cached: true marker to spare your FaxDrop quota.
Recommended polling cadence: every ~5s for the first 2 min, then every ~30s for up to 10 min, stop on terminal status.
Required:
faxId (string)Returns: { id, status, recipientNumber?, pages?, completedAt?, _cached? }
| Knob | Env var | Default | Notes |
|---|---|---|---|
| Outbox jail | FAXDROP_MCP_WORK_DIR=/abs/path |
~/FaxOutbox/ (auto-created mode 0o700) |
Every filePath must live inside this directory after realpath canonicalization. Symlinks to outside the outbox are rejected. |
| Number gate | FAXDROP_MCP_NUMBER_GATE=open|pairing|closed |
pairing |
pairing requires HITL approval via faxdrop_pair_number before a new number can be faxed. closed disables runtime pairing (paired.json edited out-of-band). |
| Allowed types | FAXDROP_MCP_ALLOWED_TYPES=... |
FIXED_LINE,FIXED_LINE_OR_MOBILE,VOIP,TOLL_FREE |
libphonenumber NumberType allow-list. |
| Allowed countries | FAXDROP_MCP_ALLOWED_COUNTRIES=... |
US,CA,PR,GU,VI,AS,MP |
ISO-3166-1 alpha-2 allow-list (US/CA + US territories). |
| State directory | FAXDROP_MCP_STATE_DIR=/abs/path |
~/.faxdrop-mcp/ (mode 0o700) |
Where paired.json lives (mode 0o600, atomic write). |
| Dry run | FAXDROP_MCP_DRY_RUN=true |
off | Write tools (faxdrop_send_fax, faxdrop_pair_number) return the would-be payload (passed through the same allowlist redaction as the audit log — see row below) and never call FaxDrop or touch paired.json. |
| Audit log | FAXDROP_MCP_AUDIT_LOG=/abs/path/audit.log |
off | Append-only JSON Lines (file mode 0o600). Allowlist-based redaction: only FaxDrop response-shape fields (recipientNumber, faxId, id) are kept in clear; known credential keys (apiKey / authorization / password / secret / token) are replaced with [REDACTED]; every other field is elided with a [ELIDED:NNN] length marker. This is a fail-closed design: a new API field added upstream is hidden by default, not leaked. |
Every failure is returned as isError: true with a structured error_type, message, and (when applicable) hint and retry_after. Programmatic consumers can match on error_type (in structuredContent) to drive retry logic.
error_type |
Layer | Trigger | Suggested action |
|---|---|---|---|
phone_parse |
input | Recipient number can't be parsed by libphonenumber. | Ask user for an E.164 number. |
phone_type |
policy | Phone type (e.g. MOBILE) not in FAXDROP_MCP_ALLOWED_TYPES. |
Use a fax line, or extend the env var. |
phone_country |
policy | Country not in FAXDROP_MCP_ALLOWED_COUNTRIES. |
Confirm with the user; extend the env var if intentional. |
phone_gate |
policy | Number not in paired.json and gate is pairing or closed. |
In pairing mode: call faxdrop_pair_number first. In closed: edit paired.json out-of-band. |
pair_disabled |
policy | faxdrop_pair_number called outside pairing mode. |
Set FAXDROP_MCP_NUMBER_GATE=pairing. |
bad_request |
filesystem | Path is relative, outside outbox, leaf-symlink, missing, oversized, or has an unsupported extension. | The accompanying hint describes the exact remedy. |
unauthorized |
upstream | FaxDrop returned 401. | Check FAXDROP_API_KEY in your MCP client config. |
payment_required |
upstream | FaxDrop returned 402 (out of credits). | Top up at the FaxDrop pricing page. |
rate_limited |
upstream | FaxDrop returned 429. | Wait retry_after seconds; the hint shows the bucket that was hit. |
invalid_response |
upstream | FaxDrop returned a non-JSON body (proxy interception, incident page). | Body is discarded for safety; check FaxDrop status page. |
fax_error |
upstream (fallback) | FaxDrop returned an error with no error_type field. |
Read the message; treat as transient. |
Two independent caps gate every fax send, both enforced by FaxDrop:
429 rate_limited with retry_after and X-RateLimit-* headers.402 payment_required when you run out, with a top-up hint.The MCP does not add its own limiter; it forwards FaxDrop's response as a clean isError: true with error_type, hint, and retry_after. See FaxDrop's API docs for the current numbers.
faxdrop_send_fax. This is also baked into the tool description.FAXDROP_MCP_DRY_RUN=true.See ROADMAP.md.
Other MCP servers in the klodr family:
PRs welcome. See CONTRIBUTING.md for the test/build/lint checklist and release process.
MIT — see LICENSE.
Добавь это в claude_desktop_config.json и перезапусти Claude Desktop.
{
"mcpServers": {
"faxdrop-mcp": {
"command": "npx",
"args": []
}
}
}Web content fetching and conversion for efficient LLM usage.
Retrieval from AWS Knowledge Base using Bedrock Agent Runtime.
Provides auto-configuration for setting up an MCP server in Spring Boot applications.
A very streamlined mcp client that supports calling and monitoring stdio/sse/streamableHttp, and can also view request responses through the /logs page. It also