Démarrage rapide du serveur MCP
Le serveur MCP (Model Context Protocol) d'Owning permet à tout client IA compatible MCP — Claude Desktop, GPT, Cursor ou tout agent personnalisé — de rechercher, parcourir, créer et gérer des annonces sur Owning.pro sans écrire de code HTTP. Il encapsule l'API REST dans 10 outils simples exposés via JSON-RPC 2.0.
Qu'est-ce que le serveur MCP ?
Le serveur MCP est une couche légère qui traduit les requêtes du protocole MCP en appels HTTP vers l'API REST d'Owning. Au lieu de construire des requêtes HTTP avec des en-têtes, des URL et des corps JSON, un agent IA appelle simplement un outil comme search_listings ou create_listing avec des arguments structurés.
Plus simple pour les agents — les outils ont des paramètres typés et des descriptions, donc le LLM sait exactement quoi passer.
Pas de code HTTP récurrent — le serveur gère les en-têtes d'authentification, la construction des URL et l'analyse des réponses.
Résultats structurés — les résultats reviennent sous forme de contenu textuel (JSON ou Markdown) prêts pour le raisonnement du LLM.
Architecture
MCP Client (Claude Desktop, GPT, Cursor, custom agent)
| MCP protocol (JSON-RPC 2.0 over HTTP)
v
MCP Server (https://mcp.owning.pro)
| HTTP calls to api.owning.pro
v
Owning API (https://api.owning.pro)Connexion au serveur MCP
URL du serveur
| Endpoint | Méthode | Objectif |
|---|---|---|
https://mcp.owning.pro/mcp | POST | Requête JSON-RPC 2.0 → réponse |
https://mcp.owning.pro/mcp/sse | GET | SSE keepalive (pour les clients qui attendent du SSE) |
https://mcp.owning.pro/health | GET | Vérification de l'état + liste des outils |
Protocole
Le serveur implémente le transport MCP Streamable HTTP (spec 2025-03-26). Chaque requête POST /mcp est un cycle complet de requête → réponse JSON-RPC 2.0. Aucune connexion persistante n'est nécessaire.
Authentification
Passez votre clé API Owning en tant que token Bearer dans l'en-tête Authorization :
Authorization: Bearer own_aBcD123eFgH456iJkL789mNoP012qRsT345uVwX678yZ- Outils de lecture (recherche, consultation, catégories, types d'actifs) — clé API facultative. Sans clé, les requêtes sont anonymes (soumises aux limites de débit publiques : 100 req/min par IP).
- Outils d'écriture (création, téléversement, publication, gestion) — clé API requise avec permission d'écriture.
- contact_seller — clé API facultative (endpoint public, limité par IP).
Étape 1 : Initialiser
curl -X POST https://mcp.owning.pro/mcp \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {}
}'
# Response:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"protocolVersion": "2024-11-05",
"capabilities": { "tools": {} },
"serverInfo": { "name": "owning-mcp", "version": "0.2.0" }
}
}Étape 2 : Lister les outils disponibles
curl -X POST https://mcp.owning.pro/mcp \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/list",
"params": {}
}'
# Response: array of 10 tool definitions with name, description, and inputSchemaÉtape 3 : Appeler un outil
curl -X POST https://mcp.owning.pro/mcp \
-H "Content-Type: application/json" \
-H "Authorization: Bearer own_aBcD123eFgH..." \
-d '{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "search_listings",
"arguments": {
"query": "bavaria",
"category": "boats",
"limit": 5
}
}
}'
# Response:
{
"jsonrpc": "2.0",
"id": 3,
"result": {
"content": [{ "type": "text", "text": "{ \"results\": [...], \"pagination\": {...} }" }]
}
}Outils de lecture (5)
Outils en lecture seule pour rechercher et parcourir des annonces. La clé API est facultative — sans clé, les requêtes sont anonymes.
1. search_listings
Rechercher des annonces avec des filtres. Renvoie les annonces correspondantes avec titre, prix, localisation, images et attributs clés.
Paramètres
| Paramètre | Type | Requis | Défaut | Description |
|---|---|---|---|---|
query | string | No | — | Full-text search across title, description, tags, and attributes |
category | string | No | — | Category slug (e.g. boats, cars) |
brand | string | No | — | Filter by brand (passed as attr[brand]) |
min_price | number | No | — | Minimum price filter |
max_price | number | No | — | Maximum price filter |
location | string | No | — | Filter by location (country or city) |
limit | integer | No | 20 | Results per page (max 100) |
offset | integer | No | 0 | Pagination offset |
# Example: search for Bavaria boats under 150k
{
"name": "search_listings",
"arguments": {
"query": "bavaria",
"category": "boats",
"max_price": 150000,
"limit": 10
}
}2. get_listing
Obtenir les détails complets d'une annonce spécifique par ID ou slug. Renvoie toutes les informations disponibles, y compris la description, les spécifications, toutes les images, les prix, la localisation et les attributs.
Paramètres
| Paramètre | Type | Requis | Description |
|---|---|---|---|
id_or_slug | string | Yes | Listing ID (ULID) or slug (e.g. azimut-95-magellano-2024) |
3. get_listing_markdown
Obtenir une annonce au format Markdown — optimisé pour les agents et la consommation par l'IA. Inclut toutes les données de l'annonce (titre, prix, description, spécifications, images, attributs) dans un document Markdown structuré et lisible avec un frontmatter YAML.
Paramètres
| Paramètre | Type | Requis | Description |
|---|---|---|---|
id_or_slug | string | Yes | Listing ID (ULID) or slug |
# Example response content:
---
title: "Lagoon 400 S2"
price: 295000
currency: "EUR"
condition: "good"
---
## Description
Gebrauchtboot; Baujahr 2016
## Specifications
- **Brand**: lagoon
- **Year**: 2016
- **Length**: 11.97 m4. list_categories
Lister toutes les catégories disponibles sur Owning.pro avec leur nombre d'annonces. Renvoie un arbre hiérarchique de catégories (parent et sous-catégories) avec les noms de slug et les nombres d'éléments. Aucun paramètre requis.
5. get_asset_type
Obtenir le modèle d'attributs pour une catégorie spécifique. Indique quels champs/attributs sont disponibles pour les annonces dans cette catégorie (par ex. marque, modèle, année, longueur pour les bateaux).
Paramètres
| Paramètre | Type | Requis | Description |
|---|---|---|---|
category | string | Yes | Category slug / asset type ID (e.g. boats, cars) |
Outils d'écriture (5)
Outils d'écriture pour créer, publier et gérer des annonces. Tous nécessitent une clé API avec permission d'écriture, à l'exception de contact_seller qui est public.
6. create_listing
Créer une nouvelle annonce sur Owning.pro. L'annonce est créée avec le statut brouillon — utilisez publish_listing pour la rendre visible publiquement. Limite de débit : 10 annonces par jour et par utilisateur.
Paramètres
| Paramètre | Type | Requis | Description |
|---|---|---|---|
title | string | Yes | 5–120 characters |
description | string | Yes | 20–5000 characters |
category_id | string | Yes | Category ID (use list_categories to find available) |
condition | enum | Yes | new, like_new, good, fair, poor, refurbished |
type | enum | No | sale (default) or wanted |
price | object | Yes | { amount, currency?, negotiable? } — currency defaults to EUR |
location | object | Yes | { country, city, postal_code?, lat?, lng?, shipping? } |
images | array | No | Up to 10: [{ url, alt? }]}. Use upload_image first. |
attributes | object | No | Category-specific attributes (use get_asset_type to discover) |
tags | array | No | Up to 10 tags, each 1–50 characters |
{
"name": "create_listing",
"arguments": {
"title": "Apple iPhone 13 128GB Blue",
"description": "Apple iPhone 13 in blue, 128GB. Good condition, battery health 89%.",
"category_id": "electronics",
"condition": "good",
"price": { "amount": 399, "currency": "EUR", "negotiable": true },
"location": { "country": "ES", "city": "Madrid", "shipping": true },
"tags": ["iphone", "apple", "smartphone"]
}
}7. upload_image
Téléverser une image sur Owning.pro. Passez l'image en tant que données encodées en base64. Si listing_id est fourni, l'image est attachée à cette annonce (nécessite la propriété). Si omis, un téléversement autonome renvoie une URL à utiliser dans create_listing. Limite de débit : 50 images par jour. Formats pris en charge : jpg, png, webp, heic, heif, avif. Taille maximale : 10 Mo.
Paramètres
| Paramètre | Type | Requis | Description |
|---|---|---|---|
image_data | string | Yes | Base64-encoded image data (without data: prefix) |
filename | string | Yes | Original filename including extension (e.g. photo.jpg) |
listing_id | string | No | Listing ID or slug. If provided, attaches to that listing. |
8. publish_listing
Publier une annonce brouillon, la rendant visible publiquement sur Owning.pro. Fait passer l'annonce du statut brouillon au statut actif. Seul le propriétaire de l'annonce peut la publier.
Paramètres
| Paramètre | Type | Requis | Description |
|---|---|---|---|
id_or_slug | string | Yes | Listing ID or slug of the draft listing to publish |
9. contact_seller
Contacter le vendeur d'une annonce en envoyant un message. L'email du vendeur n'est jamais exposé — l'API relaie le message par email et le vendeur peut répondre à votre email. Aucune clé API requise (endpoint public). Limite de débit : 5 contacts par heure et par IP.
Paramètres
| Paramètre | Type | Requis | Description |
|---|---|---|---|
id_or_slug | string | Yes | Listing ID or slug |
name | string | Yes | Your name (shown to the seller, 1–100 chars) |
email | string | Yes | Your email (the seller can reply to this) |
message | string | Yes | Your message (1–2000 characters) |
10. manage_listing
Gérer une annonce existante — mettre à jour ses champs, changer son statut ou la supprimer. Seul le propriétaire de l'annonce peut effectuer ces actions. Prend en charge trois actions :
Paramètres
| Paramètre | Type | Requis | Description |
|---|---|---|---|
id_or_slug | string | Yes | Listing ID or slug to manage |
action | enum | Yes | update, change_status, or delete |
status | enum | For change_status | active, paused, or sold |
title, description, price, etc. | various | For update | Any listing field to update (see create_listing for the full list) |
# Example: pause a listing
{
"name": "manage_listing",
"arguments": {
"id_or_slug": "apple-iphone-13-128gb-blue",
"action": "change_status",
"status": "paused"
}
}
# Example: update the price
{
"name": "manage_listing",
"arguments": {
"id_or_slug": "apple-iphone-13-128gb-blue",
"action": "update",
"price": { "amount": 350, "currency": "EUR", "negotiable": false }
}
}
# Example: delete a listing
{
"name": "manage_listing",
"arguments": {
"id_or_slug": "apple-iphone-13-128gb-blue",
"action": "delete"
}
}Limites de débit
Le serveur MCP transfère toutes les requêtes à l'API REST d'Owning, donc les limites de débit de l'API s'appliquent :
| Outil | Limite | Portée |
|---|---|---|
| Read tools (no API key) | 100 req/min | per IP |
| Read tools (with API key) | 300 req/min | per key |
create_listing | 10 req/day | per user |
upload_image | 50 req/day | per user |
contact_seller | 5 req/hour | per IP |
Gestion des erreurs
Les erreurs d'outil sont renvoyées en tant que résultats MCP avec isError: true et un message d'erreur dans le contenu :
{
"jsonrpc": "2.0",
"id": 4,
"result": {
"content": [{ "type": "text", "text": "Search failed: Rate limit exceeded (status 429)" }],
"isError": true
}
}Les arguments invalides (échecs de validation du schéma) sont également renvoyés en tant que résultats isError avec une description des champs en échec.
Vérification de l'état
curl https://mcp.owning.pro/health
# Response:
{
"status": "ok",
"service": "owning-mcp",
"version": "0.2.0",
"timestamp": "2026-07-11T16:17:44.333Z",
"apiBaseUrl": "https://api.owning.pro",
"tools": [
"search_listings", "get_listing", "get_listing_markdown",
"list_categories", "get_asset_type",
"create_listing", "upload_image", "publish_listing",
"contact_seller", "manage_listing"
]
}Consultez le exemple d'intégration du serveur MCP pour un guide complet de bout en bout en Python et JavaScript.