Skip to main content
Glama
padzup

Linkavista MCP

by padzup
README.md
# Linkavista MCP (Annonceur)

Vibecodé par **Arthur Valverde**, fondateur de [Padzup Agency](https://padzup.agency). Retrouvez-moi sur X : [@Arthur_Valverde](https://x.com/Arthur_Valverde).

> ⚠️ **Projet non officiel.** Ce connecteur n'est ni développé ni maintenu par Linkavista. Il a été développé de façon indépendante à partir de la documentation publique de l'API : https://linkavista.com/api/documentation. Utilisez-le à vos risques, avec vos propres identifiants API, et vérifiez toujours vos commandes avant validation.

Serveur MCP distant qui expose l'API Annonceur de Linkavista (achat de backlinks) comme outils utilisables directement en langage naturel depuis n'importe quelle session Claude, une fois connecté comme connecteur personnalisé.

Hébergé sur Cloudflare Workers, protégé par un vrai flux **OAuth 2.1** (via `@cloudflare/workers-oauth-provider`) : toute connexion doit passer par un écran de connexion avec le mot de passe que vous choisissez avant que Claude (ou qui que ce soit d'autre) puisse utiliser le moindre outil. Sans ce mot de passe, connaître l'URL du Worker ne donne accès à rien. Testé de bout en bout avant livraison : enregistrement client, refus d'un mauvais mot de passe, acceptation du bon, échange de jeton, appel MCP authentifié, appel réel vers l'API Linkavista.

## Ce qu'il expose (17 outils, vérifiés contre la doc officielle Linkavista)

Référence :
- `linkavista_list_categories`, `linkavista_list_languages`, `linkavista_list_sensitive_categories`

Catalogue :
- `linkavista_search_sites` : recherche paginée avec filtres (DA, TF, prix, langue, thème, mots-clés positionnés...)
- `linkavista_search_sites_by_domain` : recherche par domaine exact
- `linkavista_get_site` : fiche complète d'un site par ID
- `linkavista_get_site_pricing` : prix par mode de rédaction
- `linkavista_get_catalog` : export en masse (jusqu'à 10 000 sites/appel, avec synchro incrémentale via `since`)

Compte :
- `linkavista_get_balance` : solde disponible
- `linkavista_get_transactions` : historique des mouvements
- `linkavista_list_invoices` : liste des factures (le téléchargement PDF se fait depuis l'espace Linkavista)

Commandes :
- `linkavista_create_order` : passer une commande (⚠️ dépense réelle, schéma strict : `site_id`, `content_provider` platform/editor/advertiser, `anchors[]`, etc.)
- `linkavista_list_orders` / `linkavista_get_order` : lister / détail d'une commande
- `linkavista_update_order_content` : mettre à jour le contenu fourni (mode `advertiser`)
- `linkavista_cancel_order` : annuler (remboursement intégral)
- `linkavista_respond_counter_offer` : accepter/refuser une contre-offre (`reason` obligatoire pour refuser)

`linkavista_search_sites`, `linkavista_list_orders`, `linkavista_get_transactions` et `linkavista_list_invoices` acceptent un objet `query` libre pour les filtres additionnels non couverts explicitement. Voir https://linkavista.com/api/documentation pour la liste complète des paramètres.

## 1. Prérequis

- Un compte Cloudflare (gratuit) : https://dash.cloudflare.com/sign-up
- Node.js 18+ et npm (déjà utilisés pour générer ce projet)
- Une clé API Linkavista de type **Annonceur** (Réglages → API sur linkavista.com), **avec son secret associé** : Linkavista fournit les deux ensemble (`X-Api-Key` + `X-Api-Secret`). Ne confondez pas avec les clés Catalogue, Inscription de sites ou Cheap-backlinks.

## Installation automatique via un agent IA (raccourci)

Si vous utilisez un agent IA avec accès à un terminal (Claude Code ou équivalent), vous pouvez lui coller le prompt ci-dessous une fois le dépôt cloné : il exécute lui-même les étapes 2 à 7 en vous laissant saisir vos clés et votre mot de passe en interactif, sans jamais les manipuler à votre place. Sinon, passez directement aux étapes manuelles juste après.

```
Installe et déploie ce serveur MCP Linkavista pour moi. Contexte : ce dépôt
contient un serveur MCP qui expose l'API Annonceur de Linkavista comme des
outils utilisables depuis Claude ou tout autre client MCP. Il doit être
déployé sur MON propre compte Cloudflare Workers, avec MES identifiants
Linkavista et un mot de passe que je choisis. Rien n'est partagé avec le
créateur du dépôt.

Suis ces étapes dans l'ordre, dans le dossier de ce dépôt cloné :

1. Vérifie que Node.js 18+ et npm sont installés (`node -v`, `npm -v`). Si
   absents, arrête-toi et demande-moi de les installer.
2. Installe les dépendances : `npm install`. Si npm bloque des postinstall
   scripts (core-js-pure, esbuild, workerd), lance
   `npm install-scripts approve core-js-pure esbuild workerd` puis relance
   `npm install`.
3. Connecte mon compte Cloudflare : `npx wrangler login`. Ça ouvre une
   fenêtre de navigateur, laisse-moi l'autoriser moi-même.
4. Crée le fichier de config local : `cp wrangler.jsonc.example wrangler.jsonc`.
5. Crée le stockage KV : `npx wrangler kv namespace create OAUTH_KV`.
   Récupère l'`id` affiché et remplace `REMPLACER_PAR_ID_KV_OAUTH` par cette
   valeur dans `wrangler.jsonc` (le fichier que tu viens de créer, pas le
   `.example`).
6. Demande-moi ma clé API Linkavista Annonceur et son secret associé, puis
   lance ces trois commandes une par une en me laissant saisir chaque valeur
   au prompt interactif (ne passe JAMAIS ces valeurs en argument de commande
   ou dans un fichier) :
   - `npx wrangler secret put LINKAVISTA_API_KEY`
   - `npx wrangler secret put LINKAVISTA_API_SECRET`
   - `npx wrangler secret put OWNER_PASSWORD` (je choisis un mot de passe ici)
7. Déploie : `npm run deploy`. Note l'URL affichée
   (`https://linkavista-mcp.<mon-sous-domaine>.workers.dev`).
8. Vérifie que ça répond :
   `curl https://linkavista-mcp.<mon-sous-domaine>.workers.dev/` doit
   renvoyer "Linkavista MCP server: OK...".
9. Donne-moi l'URL finale suivie de `/mcp` à coller dans Claude (Réglages →
   Connecteurs → Ajouter un connecteur personnalisé), et rappelle-moi qu'à la
   première connexion, Claude m'ouvrira un écran de connexion où je devrai
   saisir le mot de passe choisi à l'étape 6.

Ne stocke, n'affiche et ne commite jamais mes clés API, mon secret ou mon mot
de passe en clair où que ce soit : ils doivent seulement transiter par les
prompts interactifs de wrangler.
```

## 2. Installation

```bash
cd linkavista-mcp
npm install
```

## 3. Connexion à votre compte Cloudflare

```bash
npx wrangler login
```

Une fenêtre de navigateur s'ouvre pour autoriser Wrangler sur votre compte.

## 4. Créer le stockage OAuth (KV)

D'abord, créez votre fichier de configuration local à partir du template fourni (`wrangler.jsonc` est volontairement ignoré par git : il contiendra votre identifiant de namespace, propre à votre compte Cloudflare) :

```bash
cp wrangler.jsonc.example wrangler.jsonc
```

Le système de connexion a besoin d'un petit espace de stockage Cloudflare (KV) pour retenir les sessions/jetons :

```bash
npx wrangler kv namespace create OAUTH_KV
```

Ça affiche un identifiant du type `id = "abcd1234..."`. Ouvrez `wrangler.jsonc` (celui que vous venez de créer, pas le `.example`), et remplacez `REMPLACER_PAR_ID_KV_OAUTH` par cet identifiant exact (gardez les guillemets).

## 5. Configuration des secrets

Aucune de ces valeurs ne doit être écrite en dur dans le code. Elles sont stockées comme secrets Cloudflare, chiffrées et jamais exposées à Claude ni visibles dans le code source :

```bash
npx wrangler secret put LINKAVISTA_API_KEY
# collez votre clé API Annonceur (X-Api-Key) quand demandé

npx wrangler secret put LINKAVISTA_API_SECRET
# collez le secret associé (X-Api-Secret) quand demandé

npx wrangler secret put OWNER_PASSWORD
# choisissez un mot de passe que VOUS seul connaîtrez : c'est lui qu'on vous
# redemandera à chaque fois que vous (re)connectez Claude à ce serveur
```

## 6. Déploiement

```bash
npm run deploy
```

Wrangler affiche l'URL de votre Worker, du type :

```
https://linkavista-mcp.<votre-sous-domaine>.workers.dev
```

L'endpoint MCP est cette URL suivie de `/mcp`, par exemple :
`https://linkavista-mcp.<votre-sous-domaine>.workers.dev/mcp`

Vérification rapide (doit répondre "Linkavista MCP server: OK...") :

```bash
curl https://linkavista-mcp.<votre-sous-domaine>.workers.dev/
```

## 7. Connexion depuis Claude

Dans les réglages Claude (claude.ai) → Connecteurs → Ajouter un connecteur personnalisé, collez l'URL `/mcp` ci-dessus (sans rien ajouter). Claude détecte automatiquement que le serveur exige une connexion OAuth et ouvre un écran de connexion : c'est notre page, avec votre mot de passe (`OWNER_PASSWORD`) à saisir. Une fois autorisé, les 17 outils Linkavista sont disponibles dans **toute nouvelle session Claude** sur votre compte, sans rien reconfigurer.

Si vous déconnectez puis reconnectez le connecteur plus tard, il vous redemandera ce même mot de passe.

## 8. Développement / test en local (optionnel)

```bash
cp .dev.vars.example .dev.vars
# éditez .dev.vars et renseignez vos vraies valeurs (ou des valeurs de test)
npm run dev
```

Le serveur écoute sur `http://localhost:8787`, endpoint `http://localhost:8787/mcp`. En local, `wrangler dev` simule automatiquement le stockage KV, pas besoin d'un vrai namespace pour tester.

## 9. Limites à connaître

- Rate limit Linkavista par défaut : 200 requêtes/minute, avec un plafond quotidien. L'API répond `429` avec `retry_after` en cas de dépassement.
- `linkavista_create_order` engage une vraie dépense sur le solde du compte. Vérifiez toujours le prix via `linkavista_get_site_pricing` et le solde via `linkavista_get_balance` avant de commander.
- Ce serveur ne gère que l'API **Annonceur** (achat).
- Pour mettre à jour le serveur après une modification de `src/index.ts`, relancez simplement `npm run deploy`.
- L'écran `/authorize` limite les tentatives de mot de passe à 5 par IP toutes les 15 minutes (compteur KV, best-effort, pas atomique), avec comparaison à temps constant. Ça bloque le brute-force séquentiel naïf, pas un attaquant qui parallélise ses requêtes (KV n'est pas fait pour ça ; un Durable Object serait la vraie solution).

## Licence

MIT. Voir [LICENSE](./LICENSE).