{
  "markdown": "# dropscan-mcp\n\nMCP (Model Context Protocol) server for the [Dropscan](https://dropscan.de) postal-mail-to-email API. Dropscan receives your physical letters at a scanbox; this server lets your MCP client list mailings, download the scans (PDF / ZIP / envelope image / OCR text), and, when explicitly enabled, request actions (scan / forward / destroy) and manage recipients, forwarding addresses and webhook rules.\n\nmcp-name: io.github.bitterdev/dropscan-mcp\n\n## Safety first: Dropscan has no sandbox\n\nEvery request hits the **real production account**. Actions are irreversible: a **destroyed letter is physically shredded and gone**, a **forward** physically mails the letter and costs money.\n\nBecause of that, all write/action tools are gated **twice**:\n\n1. **`DROPSCAN_ALLOW_WRITES`** environment flag. Unless it is set to `1`/`true`/`yes`, every non-GET tool refuses to run. It is **disabled by default**.\n2. **`confirm: true`** parameter. Each write/action tool takes an explicit `confirm` argument (default `false`) and refuses unless it is `true`.\n\nRead-only `GET` tools are always available and never change state.\n\n## Tools\n\n### Read-only (always available)\n\n| Tool | Endpoint |\n| --- | --- |\n| `list_scanboxes` | `GET /scanboxes` |\n| `list_mailings(scanbox_id, current_status?, older_than?)` | `GET /scanboxes/{id}/mailings` |\n| `get_mailing(scanbox_id, uuid)` | `GET /scanboxes/{id}/mailings/{uuid}` |\n| `get_mailing_pdf(scanbox_id, uuid, save_path?)` | `GET .../{uuid}/pdf` |\n| `get_mailing_zip(scanbox_id, uuid, save_path?)` | `GET .../{uuid}/zip` |\n| `get_mailing_envelope(scanbox_id, uuid, save_path?)` | `GET .../{uuid}/envelope` |\n| `get_mailing_plaintext(scanbox_id, uuid)` | `GET .../{uuid}/plaintext` |\n| `list_recipients(scanbox_id)` | `GET /scanboxes/{id}/recipients` |\n| `get_recipient(scanbox_id, recipient_id)` | `GET /scanboxes/{id}/recipients/{id}` |\n| `get_forwarding_address(address_id)` | `GET /forwarding_addresses/{id}` |\n| `get_shipment(shipment_id)` | `GET /shipments/{id}` |\n| `list_webhook_rules()` | `GET /webhook_rules` |\n| `get_webhook_rule(rule_id)` | `GET /webhook_rules/{id}` |\n\nThe download tools save the asset to disk (default `~/Downloads`, override with `save_path` or the `DROPSCAN_DOWNLOAD_DIR` env var) and return the saved path, byte size and content type.\n\n### Write / action (double-gated: `DROPSCAN_ALLOW_WRITES=1` **and** `confirm=true`)\n\n| Tool | Endpoint |\n| --- | --- |\n| `request_mailing_action(scanbox_id, mailing_uuid, action_type, forwarding_address_id?, forwarding_date?, confirm)` | `POST .../{uuid}/action_requests` |\n| `cancel_mailing_action(scanbox_id, mailing_uuid, action_request_id, confirm)` | `DELETE .../{uuid}/action_requests/{id}` |\n| `set_mailing_recipient(scanbox_id, mailing_uuid, recipient_id, confirm)` | `PUT .../{uuid}/recipient` |\n| `create_recipient(scanbox_id, type, firstname?, lastname?, name?, confirm)` | `POST /scanboxes/{id}/recipients` |\n| `create_forwarding_address(firstname, lastname, street, number, zip_code, city, country_code, company?, info?, state?, confirm)` | `POST /forwarding_addresses` |\n| `create_webhook_rule(url, events, authorization_header?, confirm)` | `POST /webhook_rules` |\n| `update_webhook_rule(rule_id, url?, events?, authorization_header?, confirm)` | `PATCH /webhook_rules/{id}` |\n| `delete_webhook_rule(rule_id, confirm)` | `DELETE /webhook_rules/{id}` |\n\n**`action_type`** is one of `scan`, `forward`, `destroy` (exact enum from the API). For `forward`, both `forwarding_address_id` and `forwarding_date` (ISO `YYYY-MM-DD`) are required.\n\n**Webhook `events`**: `mailing_received`, `scan_requested`, `mailing_scanned`, `mailing_archived`, `mailing_trashed`, `mailing_shredded`, `mailing_added_to_shipment`, `mailing_removed_from_shipment`, `shipment_sent`, `package_tracking_updated`.\n\n## Requirements\n\n- Python >= 3.10\n- A Dropscan personal access token\n\n## Installation\n\nFrom a local clone:\n\n```bash\npython3 -m venv .venv\n./.venv/bin/pip install .\n```\n\n## Configuration\n\nThe token is read from the `DROPSCAN_TOKEN` environment variable and sent as `Authorization: Bearer <token>`. It is never hardcoded.\n\n### Claude Code\n\n```bash\nclaude mcp add dropscan -e DROPSCAN_TOKEN=\"dspat-...\" -- dropscan-mcp\n```\n\n### Claude Desktop / generic MCP client\n\n```json\n{\n  \"mcpServers\": {\n    \"dropscan\": {\n      \"command\": \"/absolute/path/to/dropscan-mcp/.venv/bin/python\",\n      \"args\": [\"-m\", \"dropscan_mcp.server\"],\n      \"env\": {\n        \"DROPSCAN_TOKEN\": \"dspat-...\"\n      }\n    }\n  }\n}\n```\n\nTo enable the write/action tools, add `\"DROPSCAN_ALLOW_WRITES\": \"1\"` to `env`. Leave it out to keep the server strictly read-only.\n\nThe server runs over stdio.\n\n## Environment variables\n\n| Variable | Description |\n| --- | --- |\n| `DROPSCAN_TOKEN` | **Required.** Dropscan personal access token (Bearer). |\n| `DROPSCAN_ALLOW_WRITES` | Set to `1`/`true` to enable write/action tools. Default: disabled. |\n| `DROPSCAN_DOWNLOAD_DIR` | Default directory for downloaded PDFs/ZIPs/images. Default: `~/Downloads`. |\n\n## License\n\nMIT, see [LICENSE](LICENSE).\n\n## Author\n\nFabian Bitter (fabian@bitter.de)\n",
  "bytes": 5103,
  "sha": "57b8804d15aa63f084b333b369a3d9a44c0c708a8410d5b5d4586e46df79a735",
  "repo_slug": "bitterdev/dropscan-mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_bitterdev_dropscan_mcp_4a834709/readme"
}