verychic-mcp 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. verychic_mcp-0.1.0/.dockerignore +13 -0
  2. verychic_mcp-0.1.0/.github/workflows/release.yml +90 -0
  3. verychic_mcp-0.1.0/.gitignore +29 -0
  4. verychic_mcp-0.1.0/CLAUDE.md +93 -0
  5. verychic_mcp-0.1.0/DEPLOY.md +31 -0
  6. verychic_mcp-0.1.0/Dockerfile +12 -0
  7. verychic_mcp-0.1.0/LICENSE +21 -0
  8. verychic_mcp-0.1.0/PKG-INFO +109 -0
  9. verychic_mcp-0.1.0/README.md +85 -0
  10. verychic_mcp-0.1.0/pyproject.toml +38 -0
  11. verychic_mcp-0.1.0/render.yaml +9 -0
  12. verychic_mcp-0.1.0/tests/__init__.py +0 -0
  13. verychic_mcp-0.1.0/tests/fixtures/checkin_availabilities_sample.json +42 -0
  14. verychic_mcp-0.1.0/tests/fixtures/hotel_sample.json +1508 -0
  15. verychic_mcp-0.1.0/tests/fixtures/preview_sample.json +29 -0
  16. verychic_mcp-0.1.0/tests/fixtures/products_sample.json +329 -0
  17. verychic_mcp-0.1.0/tests/test_api.py +94 -0
  18. verychic_mcp-0.1.0/tests/test_discovery.py +34 -0
  19. verychic_mcp-0.1.0/tests/test_errors.py +18 -0
  20. verychic_mcp-0.1.0/tests/test_http_client.py +73 -0
  21. verychic_mcp-0.1.0/tests/test_network_smoke.py +30 -0
  22. verychic_mcp-0.1.0/tests/test_parsers.py +63 -0
  23. verychic_mcp-0.1.0/tests/test_server.py +40 -0
  24. verychic_mcp-0.1.0/verychic_mcp/__init__.py +1 -0
  25. verychic_mcp-0.1.0/verychic_mcp/api.py +72 -0
  26. verychic_mcp-0.1.0/verychic_mcp/config.py +23 -0
  27. verychic_mcp-0.1.0/verychic_mcp/discovery.py +22 -0
  28. verychic_mcp-0.1.0/verychic_mcp/errors.py +22 -0
  29. verychic_mcp-0.1.0/verychic_mcp/http_client.py +59 -0
  30. verychic_mcp-0.1.0/verychic_mcp/models.py +57 -0
  31. verychic_mcp-0.1.0/verychic_mcp/parsers.py +55 -0
  32. verychic_mcp-0.1.0/verychic_mcp/server.py +72 -0
@@ -0,0 +1,13 @@
1
+ .git
2
+ .github
3
+ docs
4
+ tests
5
+ dist
6
+ build
7
+ *.har
8
+ .superpowers
9
+ __pycache__
10
+ *.pyc
11
+ .venv
12
+ .ruff_cache
13
+ .pytest_cache
@@ -0,0 +1,90 @@
1
+ name: Release & Publish to PyPI
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+
8
+ jobs:
9
+ test:
10
+ name: Run Tests
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - name: Checkout code
14
+ uses: actions/checkout@v5
15
+
16
+ - name: Set up Python
17
+ uses: actions/setup-python@v6
18
+ with:
19
+ python-version: "3.12"
20
+
21
+ - name: Install dependencies
22
+ run: pip install -e ".[dev]"
23
+
24
+ - name: Run unit tests (offline) + lint
25
+ run: |
26
+ pytest
27
+ ruff check verychic_mcp tests
28
+
29
+ build:
30
+ name: Build Package
31
+ needs: test
32
+ runs-on: ubuntu-latest
33
+ steps:
34
+ - name: Checkout code
35
+ uses: actions/checkout@v5
36
+
37
+ - name: Set up Python
38
+ uses: actions/setup-python@v6
39
+ with:
40
+ python-version: "3.12"
41
+
42
+ - name: Build package
43
+ run: |
44
+ pip install build
45
+ python -m build
46
+
47
+ - name: Upload dist artifacts
48
+ uses: actions/upload-artifact@v5
49
+ with:
50
+ name: dist
51
+ path: dist/
52
+
53
+ publish-pypi:
54
+ name: Publish to PyPI
55
+ needs: build
56
+ runs-on: ubuntu-latest
57
+ environment: pypi
58
+ permissions:
59
+ id-token: write # OIDC trusted publishing — no token stored
60
+ steps:
61
+ - name: Download dist artifacts
62
+ uses: actions/download-artifact@v5
63
+ with:
64
+ name: dist
65
+ path: dist/
66
+
67
+ - name: Publish to PyPI
68
+ uses: pypa/gh-action-pypi-publish@release/v1
69
+
70
+ github-release:
71
+ name: Create GitHub Release
72
+ needs: publish-pypi
73
+ runs-on: ubuntu-latest
74
+ permissions:
75
+ contents: write
76
+ steps:
77
+ - name: Checkout code
78
+ uses: actions/checkout@v5
79
+
80
+ - name: Download dist artifacts
81
+ uses: actions/download-artifact@v5
82
+ with:
83
+ name: dist
84
+ path: dist/
85
+
86
+ - name: Create GitHub Release
87
+ uses: softprops/action-gh-release@v3
88
+ with:
89
+ files: dist/*
90
+ generate_release_notes: true
@@ -0,0 +1,29 @@
1
+ # Secrets / credentials — never commit
2
+ .env
3
+ .env.*
4
+ *.har
5
+ secrets.*
6
+
7
+ # Python
8
+ __pycache__/
9
+ *.py[cod]
10
+ .venv/
11
+ venv/
12
+ *.egg-info/
13
+ dist/
14
+ build/
15
+ .pytest_cache/
16
+ .ruff_cache/
17
+ .mypy_cache/
18
+
19
+ # Node (si la Phase 0 tranche pour Node/TS)
20
+ node_modules/
21
+ *.tsbuildinfo
22
+
23
+ # OS / editor
24
+ .DS_Store
25
+ .idea/
26
+ .vscode/
27
+
28
+ # Scratch de pilotage (subagent-driven-development)
29
+ .superpowers/
@@ -0,0 +1,93 @@
1
+ # CLAUDE.md — verychic-mcp
2
+
3
+ Serveur MCP **non officiel, read-only, anonyme** pour les offres d'hôtels VeryChic.
4
+ 3 outils : `verychic_list_deals`, `verychic_search_offers`, `verychic_offer_details`
5
+ (détail + disponibilité/prix par dates). HTTP pur (curl_cffi), double transport
6
+ (stdio + streamable-http). Non affilié à VeryChic — voir le disclaimer du `README.md`.
7
+
8
+ ## Les 4 principes à intégrer
9
+
10
+ 1. **Think Before Coding** — expliciter les hypothèses ; si plusieurs interprétations, les présenter (ne pas trancher en silence) ; si plus simple existe, le dire ; si flou, s'arrêter et demander.
11
+ 2. **Simplicity First** — code minimal qui résout le problème ; rien de spéculatif ; pas d'abstraction pour usage unique ; si 200 lignes pour 50, réécrire.
12
+ 3. **Surgical Changes** — ne toucher que le nécessaire ; ne pas « améliorer » le code adjacent ; matcher le style existant ; signaler le dead code, ne pas le supprimer ; nettoyer seulement les orphelins créés par ses propres changements.
13
+ 4. **Goal-Driven Execution** — transformer la tâche en critères vérifiables (« fix the bug » → « écrire un test qui le reproduit puis le faire passer ») ; plan bref multi-étapes avec vérification par étape.
14
+
15
+ ## Commandes
16
+
17
+ ```bash
18
+ pip install -e ".[dev]" # installer (deps : curl_cffi, mcp[cli])
19
+ pytest # tests hors-ligne (fixtures) — exclut @network
20
+ pytest -m network # smoke-test réseau réel (touche l'API live, faible volume)
21
+ ruff check verychic_mcp tests # lint
22
+ verychic-mcp --help # CLI (transports stdio / streamable-http)
23
+ verychic-mcp # lance en stdio (défaut)
24
+ python -m build # construit le wheel (publication)
25
+ ```
26
+
27
+ Tests **hors-ligne** : ils tournent sur des fixtures JSON réelles dans `tests/fixtures/`
28
+ (capturées en Phase 0), aucune dépendance réseau. Le smoke `@network` est opt-in et
29
+ exclu de la CI par défaut (`addopts = "-m 'not network'"`).
30
+
31
+ ## Architecture (une responsabilité par module, testable isolément)
32
+
33
+ ```
34
+ config.py → constantes : routes, PRODUCT_PARAMS, rate-limit, fallback channelVersion
35
+ errors.py → VeryChicError + CloudflareBlocked / NotFound / UpstreamError (messages actionnables)
36
+ http_client.py → VeryChicClient : session curl_cffi (empreinte Chrome), rate-limit injectable,
37
+ classify_block() mappe les réponses HTTP en exceptions. get_json / get_text.
38
+ discovery.py → get_channel_version() : lit channelVersion sur le site live, fallback en dur
39
+ models.py → dataclasses Offer / Availability / OfferDetails (+ offer_url, cheapest_price)
40
+ parsers.py → JSON brut → modèles (tolérant aux champs manquants via .get)
41
+ api.py → list_deals / search_offers / offer_details : compose client + routes + parsers
42
+ server.py → FastMCP : enregistre les 3 outils, resolve_transport(), main()
43
+ ```
44
+
45
+ Flux d'un appel : `server` (outil) → `api` (route + params) → `http_client.get_json` → `parsers` → modèle sérialisé en dict.
46
+
47
+ ## Spécificités de l'API VeryChic
48
+
49
+ - Base unifiée : `https://api.verychic.com/verychic-endpoints/v1` (+ `search.verychic.com`).
50
+ Tout est **public/anonyme** (200 sans login), **pas de challenge Cloudflare** (confirmé en Phase 0).
51
+ - **`memberStatus=PROSPECT`** = visiteur anonyme (valeur d'enum valide ; `P` est rejeté en 422).
52
+ Centralisé dans `config.PRODUCT_PARAMS` — un seul endroit à changer.
53
+ - Deux types de `source` dans le catalogue, à router différemment dans `offer_details` :
54
+ - `ORCHESTRA` (hôtel) → base `/hotel/{source}/{id}.json` ; dispo via `/product/.../checkin-availabilities.json` (200).
55
+ - `ORCHESTRA_TO` (package tour-op) → base `/vacation-package/{source}/{id}.json` ; `checkin-availabilities` répond **400** → la dispo est **best-effort** (catch `NotFound`/`UpstreamError` → `[]`, mais on laisse remonter `CloudflareBlocked`).
56
+ - Page d'offre côté site : `https://www.verychic.fr/p/{externalId}/{urlName}` (→ `Offer.offer_url`).
57
+ - `channelVersion` (paramètre volatil de `preview.json`) est auto-découvert, avec fallback en dur dans `config.py`.
58
+
59
+ ## Conventions
60
+
61
+ - **Read-only, anonyme, faible volume** : aucun credential, aucune écriture/réservation, rate-limit ≥ 1 s entre requêtes (dans `http_client`). Posture défensive : pas d'extraction massive, pas de contournement Cloudflare.
62
+ - **Erreurs actionnables** : toujours via les exceptions de `errors.py`, jamais un stacktrace brut.
63
+ - **TDD + fixtures réelles** : pour toute évolution des parsers/API, ajouter/étendre un test hors-ligne sur une fixture. Un changement de comportement face à l'API live se valide via le smoke `@network`.
64
+ - Messages de commit / docs en français ; README en anglais (convention OSS).
65
+
66
+ ## Publication / Release
67
+
68
+ Repo public : **https://github.com/jordantete/verychic-mcp**.
69
+
70
+ La publication PyPI est **automatisée par `.github/workflows/release.yml`** au push d'un
71
+ tag `v*` : `test → build → publish-pypi → github-release`. L'auth PyPI se fait par
72
+ **Trusted Publishing (OIDC)** — **aucun token stocké**. Setup PyPI une fois : un *trusted
73
+ publisher* (projet `verychic-mcp`, owner `jordantete`, repo `verychic-mcp`, workflow
74
+ `release.yml`, environnement `pypi`).
75
+
76
+ Publier une version (SemVer) :
77
+ ```bash
78
+ git switch main && git pull
79
+ pytest && ruff check verychic_mcp tests # doit passer avant de tagger
80
+ # bumper "version" dans pyproject.toml (X.Y.Z), puis :
81
+ git add pyproject.toml && git commit -m "chore: release vX.Y.Z"
82
+ git tag vX.Y.Z
83
+ git push origin main --tags
84
+ ```
85
+ Le workflow fait le reste (build + upload PyPI + GitHub Release). Une fois publié,
86
+ `uvx verychic-mcp` fonctionne sans cloner. Ne jamais committer de token PyPI.
87
+
88
+ ## État & suivi
89
+
90
+ MCP **fonctionnel et validé contre l'API live**, repo GitHub public, CI de release en place
91
+ (sur `main`). Reste : 1ère publication PyPI (config trusted publisher + tag) et déploiement
92
+ remote pour Cowork. Améliorations notées et suivi : projet Notion `verychic-mcp` et
93
+ `docs/superpowers/` (spec, verdict Phase 0, plans).
@@ -0,0 +1,31 @@
1
+ # Deploying VeryChic MCP for Claude.ai / Cowork
2
+
3
+ Cloud Claude clients only talk to **remote** MCP servers over HTTPS. To use VeryChic MCP from
4
+ claude.ai or Cowork, self-host it in `streamable-http` mode and add it as a custom connector.
5
+
6
+ ## Option A — Docker (anywhere)
7
+
8
+ ```bash
9
+ docker build -t verychic-mcp .
10
+ docker run -p 8000:8000 verychic-mcp
11
+ # serves streamable-http on http://localhost:8000 (put it behind HTTPS for real use)
12
+ ```
13
+
14
+ ## Option B — Render (1-click-ish)
15
+
16
+ This repo ships a `render.yaml`. On [Render](https://render.com): New → Blueprint → point it at your
17
+ fork. It builds the `Dockerfile` and exposes the server over HTTPS. Render injects `$PORT`
18
+ automatically; the container's start command already honors it.
19
+
20
+ ## Add it to Claude.ai / Cowork
21
+
22
+ 1. Copy your deployment's HTTPS URL (e.g. `https://verychic-mcp.onrender.com`).
23
+ 2. Claude settings → Connectors → **Add custom connector** → paste the URL.
24
+ 3. The three `verychic_*` tools become available in your chats.
25
+
26
+ ## Notes
27
+
28
+ - The server is **anonymous and read-only**; no secrets or environment variables are required.
29
+ - Keep it private to you / low-traffic — see the disclaimer in the README.
30
+ - Default bind host is `127.0.0.1` for local stdio use; the Docker image binds `0.0.0.0` so the
31
+ platform can route to it.
@@ -0,0 +1,12 @@
1
+ FROM python:3.12-slim
2
+
3
+ WORKDIR /app
4
+ COPY pyproject.toml README.md LICENSE ./
5
+ COPY verychic_mcp ./verychic_mcp
6
+ RUN pip install --no-cache-dir .
7
+
8
+ ENV PORT=8000
9
+ EXPOSE 8000
10
+
11
+ # Transport HTTP distant ; l'hébergeur fournit $PORT.
12
+ CMD ["sh", "-c", "verychic-mcp --transport streamable-http --host 0.0.0.0 --port ${PORT:-8000}"]
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 VeryChic MCP contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,109 @@
1
+ Metadata-Version: 2.4
2
+ Name: verychic-mcp
3
+ Version: 0.1.0
4
+ Summary: Unofficial read-only MCP server for VeryChic hotel offers
5
+ Project-URL: Homepage, https://github.com/jordantete/verychic-mcp
6
+ Project-URL: Repository, https://github.com/jordantete/verychic-mcp
7
+ Project-URL: Issues, https://github.com/jordantete/verychic-mcp/issues
8
+ Author: VeryChic MCP contributors
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: hotels,mcp,model-context-protocol,travel,verychic
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Topic :: Internet :: WWW/HTTP
16
+ Requires-Python: >=3.11
17
+ Requires-Dist: curl-cffi>=0.7
18
+ Requires-Dist: mcp[cli]>=1.2
19
+ Provides-Extra: dev
20
+ Requires-Dist: build>=1.2; extra == 'dev'
21
+ Requires-Dist: pytest>=8; extra == 'dev'
22
+ Requires-Dist: ruff>=0.6; extra == 'dev'
23
+ Description-Content-Type: text/markdown
24
+
25
+ # VeryChic MCP
26
+
27
+ An **unofficial, read-only** [Model Context Protocol](https://modelcontextprotocol.io) server for
28
+ [VeryChic](https://www.verychic.fr) hotel flash-sale offers. Search current deals, filter them, and
29
+ get an offer's details with availability and prices by date — straight from your MCP client.
30
+
31
+ > ⚠️ **Disclaimer.** This project is **not affiliated with, endorsed by, or connected to VeryChic /
32
+ > VeryChic SAS** in any way. It is an independent, community tool for **personal use**. It accesses
33
+ > VeryChic's public web API the same way a browser does. You are responsible for complying with
34
+ > VeryChic's Terms (Conditions Générales de Vente — notably Art. 9 on intellectual property and the
35
+ > *sui generis* database right). Use it at your own risk, for personal, low-volume browsing only.
36
+ > Do not use it for bulk extraction or redistribution of VeryChic's data.
37
+
38
+ ## What it does
39
+
40
+ Three tools:
41
+
42
+ | Tool | Description |
43
+ |---|---|
44
+ | `verychic_list_deals` | The current VeryChic offers (limit configurable). |
45
+ | `verychic_search_offers` | Filter offers by `destination` (substring), `country` (exact), and/or `max_price`. |
46
+ | `verychic_offer_details` | An offer's content (advantages, gallery) **plus availability and prices by date**. |
47
+
48
+ All read-only, anonymous (no login), with a built-in conservative rate limit.
49
+
50
+ ## Install & use (local — Claude Desktop / Claude Code)
51
+
52
+ Zero-install with [`uv`](https://docs.astral.sh/uv/). Add this to your MCP client config:
53
+
54
+ ```json
55
+ {
56
+ "mcpServers": {
57
+ "verychic": {
58
+ "command": "uvx",
59
+ "args": ["verychic-mcp"]
60
+ }
61
+ }
62
+ }
63
+ ```
64
+
65
+ That runs the server over **stdio**. No clone, no manual install.
66
+
67
+ To run it yourself:
68
+
69
+ ```bash
70
+ uvx verychic-mcp # stdio (default)
71
+ uvx verychic-mcp --help # see options
72
+ ```
73
+
74
+ ## Use from Claude.ai / Cowork (remote)
75
+
76
+ Cloud clients (claude.ai web, Cowork) can only talk to **remote** MCP servers over HTTPS, so you must
77
+ **self-host** the server in `streamable-http` mode and add it as a *custom connector* by URL. See
78
+ [DEPLOY.md](DEPLOY.md) for a 1-click template. Then, in Claude settings → Connectors → Add custom
79
+ connector, paste your deployment URL.
80
+
81
+ > Listing in Anthropic's official connector directory (next to Booking/Tripadvisor) is **out of
82
+ > scope**: it requires a partner review this kind of tool would not pass.
83
+
84
+ ## Tool examples
85
+
86
+ - "List the current VeryChic deals."
87
+ - "Search VeryChic offers in Spain under 600 €."
88
+ - "Get the details and dated prices for VeryChic offer ORCHESTRA 44983."
89
+
90
+ ## Development
91
+
92
+ ```bash
93
+ git clone https://github.com/jordantete/verychic-mcp.git && cd verychic-mcp
94
+ pip install -e ".[dev]"
95
+ pytest # offline tests (fixtures); excludes the @network smoke test
96
+ pytest -m network # optional: hits the live VeryChic API (low volume)
97
+ ruff check verychic_mcp tests
98
+ ```
99
+
100
+ ## How it works
101
+
102
+ VeryChic's web front-end calls a public JSON API under `https://api.verychic.com/verychic-endpoints/v1`
103
+ (plus `search.verychic.com`). This server replays those calls with a browser-like TLS fingerprint
104
+ (`curl_cffi`), parses the responses, and exposes them as MCP tools. The volatile `channelVersion`
105
+ parameter is auto-discovered from the live site, with a hardcoded fallback.
106
+
107
+ ## License
108
+
109
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,85 @@
1
+ # VeryChic MCP
2
+
3
+ An **unofficial, read-only** [Model Context Protocol](https://modelcontextprotocol.io) server for
4
+ [VeryChic](https://www.verychic.fr) hotel flash-sale offers. Search current deals, filter them, and
5
+ get an offer's details with availability and prices by date — straight from your MCP client.
6
+
7
+ > ⚠️ **Disclaimer.** This project is **not affiliated with, endorsed by, or connected to VeryChic /
8
+ > VeryChic SAS** in any way. It is an independent, community tool for **personal use**. It accesses
9
+ > VeryChic's public web API the same way a browser does. You are responsible for complying with
10
+ > VeryChic's Terms (Conditions Générales de Vente — notably Art. 9 on intellectual property and the
11
+ > *sui generis* database right). Use it at your own risk, for personal, low-volume browsing only.
12
+ > Do not use it for bulk extraction or redistribution of VeryChic's data.
13
+
14
+ ## What it does
15
+
16
+ Three tools:
17
+
18
+ | Tool | Description |
19
+ |---|---|
20
+ | `verychic_list_deals` | The current VeryChic offers (limit configurable). |
21
+ | `verychic_search_offers` | Filter offers by `destination` (substring), `country` (exact), and/or `max_price`. |
22
+ | `verychic_offer_details` | An offer's content (advantages, gallery) **plus availability and prices by date**. |
23
+
24
+ All read-only, anonymous (no login), with a built-in conservative rate limit.
25
+
26
+ ## Install & use (local — Claude Desktop / Claude Code)
27
+
28
+ Zero-install with [`uv`](https://docs.astral.sh/uv/). Add this to your MCP client config:
29
+
30
+ ```json
31
+ {
32
+ "mcpServers": {
33
+ "verychic": {
34
+ "command": "uvx",
35
+ "args": ["verychic-mcp"]
36
+ }
37
+ }
38
+ }
39
+ ```
40
+
41
+ That runs the server over **stdio**. No clone, no manual install.
42
+
43
+ To run it yourself:
44
+
45
+ ```bash
46
+ uvx verychic-mcp # stdio (default)
47
+ uvx verychic-mcp --help # see options
48
+ ```
49
+
50
+ ## Use from Claude.ai / Cowork (remote)
51
+
52
+ Cloud clients (claude.ai web, Cowork) can only talk to **remote** MCP servers over HTTPS, so you must
53
+ **self-host** the server in `streamable-http` mode and add it as a *custom connector* by URL. See
54
+ [DEPLOY.md](DEPLOY.md) for a 1-click template. Then, in Claude settings → Connectors → Add custom
55
+ connector, paste your deployment URL.
56
+
57
+ > Listing in Anthropic's official connector directory (next to Booking/Tripadvisor) is **out of
58
+ > scope**: it requires a partner review this kind of tool would not pass.
59
+
60
+ ## Tool examples
61
+
62
+ - "List the current VeryChic deals."
63
+ - "Search VeryChic offers in Spain under 600 €."
64
+ - "Get the details and dated prices for VeryChic offer ORCHESTRA 44983."
65
+
66
+ ## Development
67
+
68
+ ```bash
69
+ git clone https://github.com/jordantete/verychic-mcp.git && cd verychic-mcp
70
+ pip install -e ".[dev]"
71
+ pytest # offline tests (fixtures); excludes the @network smoke test
72
+ pytest -m network # optional: hits the live VeryChic API (low volume)
73
+ ruff check verychic_mcp tests
74
+ ```
75
+
76
+ ## How it works
77
+
78
+ VeryChic's web front-end calls a public JSON API under `https://api.verychic.com/verychic-endpoints/v1`
79
+ (plus `search.verychic.com`). This server replays those calls with a browser-like TLS fingerprint
80
+ (`curl_cffi`), parses the responses, and exposes them as MCP tools. The volatile `channelVersion`
81
+ parameter is auto-discovered from the live site, with a hardcoded fallback.
82
+
83
+ ## License
84
+
85
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,38 @@
1
+ [project]
2
+ name = "verychic-mcp"
3
+ version = "0.1.0"
4
+ description = "Unofficial read-only MCP server for VeryChic hotel offers"
5
+ readme = "README.md"
6
+ license = "MIT"
7
+ requires-python = ">=3.11"
8
+ authors = [{ name = "VeryChic MCP contributors" }]
9
+ keywords = ["mcp", "model-context-protocol", "verychic", "hotels", "travel"]
10
+ classifiers = [
11
+ "Programming Language :: Python :: 3",
12
+ "License :: OSI Approved :: MIT License",
13
+ "Operating System :: OS Independent",
14
+ "Topic :: Internet :: WWW/HTTP",
15
+ ]
16
+ dependencies = ["curl_cffi>=0.7", "mcp[cli]>=1.2"]
17
+
18
+ [project.urls]
19
+ Homepage = "https://github.com/jordantete/verychic-mcp"
20
+ Repository = "https://github.com/jordantete/verychic-mcp"
21
+ Issues = "https://github.com/jordantete/verychic-mcp/issues"
22
+
23
+ [project.optional-dependencies]
24
+ dev = ["pytest>=8", "ruff>=0.6", "build>=1.2"]
25
+
26
+ [project.scripts]
27
+ verychic-mcp = "verychic_mcp.server:main"
28
+
29
+ [tool.pytest.ini_options]
30
+ markers = ["network: test nécessitant un accès réseau réel (hors CI)"]
31
+ addopts = "-m 'not network'"
32
+
33
+ [build-system]
34
+ requires = ["hatchling"]
35
+ build-backend = "hatchling.build"
36
+
37
+ [tool.hatch.build.targets.wheel]
38
+ packages = ["verychic_mcp"]
@@ -0,0 +1,9 @@
1
+ services:
2
+ - type: web
3
+ name: verychic-mcp
4
+ runtime: docker
5
+ plan: free
6
+ dockerfilePath: ./Dockerfile
7
+ # Pas de healthCheckPath : le serveur streamable-http sert MCP sur un sous-chemin,
8
+ # "/" renverrait 404. Render retombe sur un check d'ouverture du port.
9
+ autoDeploy: false
File without changes
@@ -0,0 +1,42 @@
1
+ [
2
+ {
3
+ "date": "20/06/2026",
4
+ "price": 169,
5
+ "currency": "EUR",
6
+ "departureCityCode": "XXX",
7
+ "nights": 1,
8
+ "days": 2
9
+ },
10
+ {
11
+ "date": "21/06/2026",
12
+ "price": 169,
13
+ "currency": "EUR",
14
+ "departureCityCode": "XXX",
15
+ "nights": 1,
16
+ "days": 2
17
+ },
18
+ {
19
+ "date": "22/06/2026",
20
+ "price": 169,
21
+ "currency": "EUR",
22
+ "departureCityCode": "XXX",
23
+ "nights": 1,
24
+ "days": 2
25
+ },
26
+ {
27
+ "date": "23/06/2026",
28
+ "price": 169,
29
+ "currency": "EUR",
30
+ "departureCityCode": "XXX",
31
+ "nights": 1,
32
+ "days": 2
33
+ },
34
+ {
35
+ "date": "24/06/2026",
36
+ "price": 169,
37
+ "currency": "EUR",
38
+ "departureCityCode": "XXX",
39
+ "nights": 1,
40
+ "days": 2
41
+ }
42
+ ]