Add: download_decisive_appraisal_pdf MCP tool
The PDF host (free-justice.openapi.gov.il) requires the same x-client-id header as the search API, so a normal browser click on the URL fails. This tool carries the auth header automatically and saves the PDF to a configurable local directory. Safety properties: - SSRF guard: only download from free-justice.openapi.gov.il and pub-justice.openapi.gov.il. - Path-traversal guard: filename is reduced to its basename; arbitrary paths are stripped. - Content-type guard: rejects 200-OK responses whose body is not a real PDF (gateway sometimes returns JSON-error 200s). - Atomic write via .tmp + rename so partial downloads never replace the cached copy. - Caches by destination path; re-downloads are no-ops unless overwrite=True. DECISIVE_APPRAISER_DOWNLOAD_DIR env var configures the output dir (default: ./downloads/decisive_appraisals). 6 new unit tests cover the happy path, caching, and all four guards. End-to-end live test confirmed a 1.4MB real PDF lands on disk with valid `%PDF-1.7` header. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -176,6 +176,18 @@ class GovmapConfig:
|
||||
os.getenv("TOOL_SEARCH_DECISIVE_APPRAISALS_ENABLED", "true").lower() == "true"
|
||||
)
|
||||
)
|
||||
tool_download_decisive_appraisal_pdf_enabled: bool = field(
|
||||
default_factory=lambda: (
|
||||
os.getenv("TOOL_DOWNLOAD_DECISIVE_APPRAISAL_PDF_ENABLED", "true").lower() == "true"
|
||||
)
|
||||
)
|
||||
|
||||
# Decisive Appraiser download settings
|
||||
decisive_appraiser_download_dir: str = field(
|
||||
default_factory=lambda: os.getenv(
|
||||
"DECISIVE_APPRAISER_DOWNLOAD_DIR", "./downloads/decisive_appraisals"
|
||||
)
|
||||
)
|
||||
|
||||
def __post_init__(self):
|
||||
"""Validate configuration after initialization."""
|
||||
|
||||
Reference in New Issue
Block a user