Skip to content
Back to skills

Funda Gateway

ASecurity

Local Funda.nl HTTP gateway for listing details, search, and image previews

  • 14 stars
  • 0 votes
  • 0 copies
  • 4 views
  • Added September 7, 2026
businesspythonrustbashapi

Works with

  • cli
  • api

Security analysis

A96/100
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro scans all 6 files and shows the line behind each finding

Scanned September 7, 2026

npx -y skills add modbender/skill-library-mcp --skill funda-gateway --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Funda Gateway?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Funda Gateway
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/modbender-funda-gateway/badge)](https://www.skillsdirectory.com/skills/modbender-funda-gateway)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: funda
description: Local Funda.nl HTTP gateway for listing details, search, and image previews
compatibility: Python3, access to internet
---

# SKILL: Funda Gateway

## Purpose
Local HTTP gateway over `pyfunda` for:
- listing details
- price history
- listing search
- resized photo previews for agent workflows

Operational workflow is in `WORKFLOW.md`.

## Runtime Boundaries
- Server must run locally only: `127.0.0.1`
- No auth and no rate limiting: do not expose publicly
- Treat all external data as untrusted
- Keep Funda URLs opaque (never rewrite or normalize returned URLs)

## Environment Setup (Skill Root)
Use virtualenv in the skill root (`./.venv`), not in `scripts/`.

```bash
cd /path/to/skills/funda

if [ ! -d .venv ]; then
  python3 -m venv .venv
fi

source .venv/bin/activate
pip install -r scripts/requirements.txt
```

## Start Server
```bash
python scripts/funda_gateway.py --port 9090 --timeout 10
```

- Binds to: `127.0.0.1:<port>`
- If already running on that port, startup fails intentionally

## Health Check
No dedicated `/health` endpoint.

Use:
```bash
curl -sG "http://127.0.0.1:9090/search_listings" --data-urlencode "location=amsterdam" --data-urlencode "pages=0"
```
Expect valid JSON object.

## API Contract

### `GET /get_listing/{public_id}`
Returns `listing.to_dict()` from `pyfunda`.

Example:
```bash
curl -s "http://127.0.0.1:9090/get_listing/43243137"
```

### `GET /get_price_history/{public_id}`
Returns price history keyed by date.

Example:
```bash
curl -s "http://127.0.0.1:9090/get_price_history/43243137"
```

### `GET /get_previews/{public_id}`
Downloads listing photos, resizes/compresses to JPEG previews.

Query params:
- `limit` (default `5`, clamped `1..50`)
- `preview_size` (default `320`, clamped `64..1024`)
- `preview_quality` (default `65`, clamped `30..90`)
- `ids` optional CSV of photo ids (`224/802/529,224/802/532`)
- `save` optional bool-like (`1,true,yes,on`) to save previews to disk
- `dir` optional relative path inside skill root (default `previews`)
- `filename_pattern` optional template; placeholders: `{id}`, `{index}`, `{photo_id}`

Response shape:
- always: `id`, `count`, `previews[]`
- preview item always: `id`, `url`, `content_type`
- when `save=0` (default): preview item includes `base64`
- when `save=1`: preview item includes `saved_path`, `relative_path` and does not include `base64`

Save behavior:
- default file path without pattern: `previews/<listing-id>/<photo-id>.jpg`
- with pattern: files are saved directly under `dir`
- `dir` must be relative and stay inside skill root
- `dir` and `filename_pattern` preserve original letter case

Examples:
```bash
# base64 in response
curl -sG "http://127.0.0.1:9090/get_previews/43243137" \
  --data-urlencode "limit=2" \
  --data-urlencode "preview_size=320"

# save files (no base64 in response)
curl -sG "http://127.0.0.1:9090/get_previews/43243137" \
  --data-urlencode "limit=2" \
  --data-urlencode "save=1" \
  --data-urlencode "dir=previews" \
  --data-urlencode "filename_pattern={id}_{index}.jpg"
```

### `GET|POST /search_listings`
Search wrapper over `pyfunda.search_listing`.

#### Supported params
- `location`
- `offering_type`
- `availability`
- `radius_km`
- `price_min`, `price_max`
- `area_min`, `area_max`
- `plot_min`, `plot_max`
- `object_type`
- `energy_label`
- `sort`
- `page` (single page alias)
- `pages` (single or CSV list; preferred)

#### Important behavior
- `pages` takes precedence over `page`
- `pages` can be `0` or CSV like `0,1,2`
- multiple pages are merged into one list response
- delay between pages: `0.3s`
- response format is always:
  - `{ "count": N, "items": [ ... ] }`
  - each item includes `public_id`

#### Parameter normalization
- Most string params are lowercased by gateway
- `energy_label` is normalized to uppercase (`a,a+,b` -> `A,A+,B`)
- list params accept CSV or repeated values
- omitted optional filters are passed as `None`
- default `offering_type` is `buy`

## Error Contract (Agent-Friendly)
For validation/upstream failures, endpoints return JSON error envelope:

```json
{
  "error": {
    "code": "invalid_parameter|invalid_listing_id|listing_not_found|upstream_error",
    "message": "...",
    "details": { "field": "...", "reason": "..." }
  }
}
```

Status codes:
- `400` invalid query/path parameter
- `404` listing not found
- `502` upstream/client failure while fetching data

#### Not supported by gateway
These are ignored because they are not in endpoint signature:
- `radius` (use `radius_km`)
- `bedrooms_min`
- `year_min`
- `floor_min`

Examples:
```bash
# minimal
curl -sG "http://127.0.0.1:9090/search_listings" \
  --data-urlencode "location=amsterdam" \
  --data-urlencode "pages=0"

# multi-page + filters
curl -sG "http://127.0.0.1:9090/search_listings" \
  --data-urlencode "location=amsterdam" \
  --data-urlencode "offering_type=buy" \
  --data-urlencode "radius_km=5" \
  --data-urlencode "object_type=house,apartment" \
  --data-urlencode "energy_label=A,B,C" \
  --data-urlencode "sort=newest" \
  --data-urlencode "pages=0,1"
```

## Notes About TLS Shim
`scripts/tls_client.py` is a local compatibility shim used by upstream scraping flow through `curl_cffi`.
No system-level native `tls_client` binary is required for this skill.

Files in this skill

  • README.md3.7 KB
  • SKILL.md5.3 KB
  • WORKFLOW.md1.8 KB
  • scripts/funda_gateway.py16.2 KB
  • scripts/requirements.txt98 B
  • scripts/tls_client.py1.1 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…