MCP-Server Schnellstart
Der Owning MCP (Model Context Protocol) Server ermöglicht es jedem MCP-kompatiblen KI-Client – Claude Desktop, GPT, Cursor oder jedem benutzerdefinierten Agenten – Anzeigen auf Owning.pro zu suchen, zu durchsuchen, zu erstellen und zu verwalten, ohne HTTP-Code zu schreiben. Er umschließt die REST API in 10 einfachen Tools, die über JSON-RPC 2.0 bereitgestellt werden.
Was ist der MCP-Server?
Der MCP-Server ist eine dünne Schicht, die MCP-Protokoll-Anfragen in HTTP-Aufrufe an die Owning REST API übersetzt. Anstatt HTTP-Anfragen mit Headern, URLs und JSON-Bodys zu konstruieren, ruft ein KI-Agent einfach ein Tool wie search_listings oder create_listing mit strukturierten Argumenten auf.
Einfacher für Agenten — Tools haben typisierte Parameter und Beschreibungen, sodass das LLM genau weiß, was es übergeben muss.
Kein HTTP-Boilerplate — der Server übernimmt Auth-Header, URL-Konstruktion und Antwort-Parsing.
Strukturierte Ergebnisse — Ergebnisse kommen als Textinhalt (JSON oder Markdown) zurück, bereit für das LLM zum Schlussfolgern.
Architektur
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)Verbindung zum MCP-Server
Server-URL
| Endpoint | Methode | Zweck |
|---|---|---|
https://mcp.owning.pro/mcp | POST | JSON-RPC 2.0 Anfrage → Antwort |
https://mcp.owning.pro/mcp/sse | GET | SSE-Keepalive (für Clients, die SSE erwarten) |
https://mcp.owning.pro/health | GET | Health-Check + Tool-Liste |
Protokoll
Der Server implementiert den MCP Streamable HTTP-Transport (Spezifikation 2025-03-26). Jede POST /mcp-Anfrage ist ein vollständiger JSON-RPC 2.0 Anfrage-→-Antwort-Zyklus. Es ist keine dauerhafte Verbindung erforderlich.
Authentifizierung
Übergib deinen Owning API-Schlüssel als Bearer-Token im Authorization-Header:
Authorization: Bearer own_aBcD123eFgH456iJkL789mNoP012qRsT345uVwX678yZ- Lese-Tools (search, get, categories, asset types) – API-Schlüssel optional. Ohne Schlüssel sind Anfragen anonym (unterliegen öffentlichen Rate-Limits: 100 Anfragen/Min pro IP).
- Schreib-Tools (create, upload, publish, manage) – API-Schlüssel mit Schreibberechtigung erforderlich.
- contact_seller – API-Schlüssel optional (öffentlicher Endpoint, Rate-Limit pro IP).
Schritt 1: Initialisieren
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" }
}
}Schritt 2: Verfügbare Tools auflisten
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 inputSchemaSchritt 3: Ein Tool aufrufen
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\": {...} }" }]
}
}Lese-Tools (5)
Schreibgeschützte Tools zum Suchen und Durchsuchen von Anzeigen. API-Schlüssel ist optional – ohne einen sind Anfragen anonym.
1. search_listings
Suche nach Anzeigen mit Filtern. Gibt übereinstimmende Anzeigen mit Titel, Preis, Standort, Bildern und wichtigsten Attributen zurück.
Parameter
| Parameter | Typ | Erforderlich | Standard | Beschreibung |
|---|---|---|---|---|
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
Rufe alle Details einer bestimmten Anzeige nach ID oder Slug ab. Gibt alle verfügbaren Informationen einschließlich Beschreibung, Spezifikationen, allen Bildern, Preisen, Standort und Attributen zurück.
Parameter
| Parameter | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
id_or_slug | string | Yes | Listing ID (ULID) or slug (e.g. azimut-95-magellano-2024) |
3. get_listing_markdown
Rufe eine Anzeige im Markdown-Format ab – optimiert für Agenten und KI-Konsum. Enthält alle Anzeigedaten (Titel, Preis, Beschreibung, Spezifikationen, Bilder, Attribute) in einem strukturierten, lesbaren Markdown-Dokument mit YAML-Frontmatter.
Parameter
| Parameter | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
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
Liste alle verfügbaren Kategorien auf Owning.pro mit ihren Anzeigezahlen auf. Gibt einen hierarchischen Baum von Kategorien (übergeordnete und Unterkategorien) mit Slug-Namen und Artikelzahlen zurück. Keine Parameter erforderlich.
5. get_asset_type
Rufe die Attributvorlage für eine bestimmte Kategorie ab. Zeigt, welche Felder/Attribute für Anzeigen in dieser Kategorie verfügbar sind (z. B. Marke, Modell, Jahr, Länge für Boote).
Parameter
| Parameter | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
category | string | Yes | Category slug / asset type ID (e.g. boats, cars) |
Schreib-Tools (5)
Schreib-Tools zum Erstellen, Veröffentlichen und Verwalten von Anzeigen. Alle erfordern einen API-Schlüssel mit Schreibberechtigung, außer contact_seller, das öffentlich ist.
6. create_listing
Erstelle eine neue Anzeige auf Owning.pro. Die Anzeige wird im Entwurfsstatus erstellt – verwende publish_listing, um sie öffentlich sichtbar zu machen. Rate-Limit: 10 Anzeigen pro Tag pro Benutzer.
Parameter
| Parameter | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
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
Lade ein Bild auf Owning.pro hoch. Übergib das Bild als base64-kodierte Daten. Wenn listing_id angegeben wird, wird das Bild an diese Anzeige angehängt (erfordert Eigentümerschaft). Wenn weggelassen, gibt ein eigenständiger Upload eine URL zurück, die in create_listing verwendet werden kann. Rate-Limit: 50 Bilder pro Tag. Unterstützte Formate: jpg, png, webp, heic, heif, avif. Maximale Größe: 10 MB.
Parameter
| Parameter | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
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
Veröffentliche eine Entwurfsanzeige und mache sie öffentlich auf Owning.pro sichtbar. Verschiebt die Anzeige vom Entwurfs- in den aktiven Status. Nur der Anzeigeneigentümer kann veröffentlichen.
Parameter
| Parameter | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
id_or_slug | string | Yes | Listing ID or slug of the draft listing to publish |
9. contact_seller
Kontaktiere den Verkäufer einer Anzeige, indem du eine Nachricht sendest. Die E-Mail-Adresse des Verkäufers wird nie offengelegt – die API leitet die Nachricht per E-Mail weiter und der Verkäufer kann auf deine E-Mail antworten. Kein API-Schlüssel erforderlich (öffentlicher Endpoint). Rate-Limit: 5 Kontakte pro Stunde pro IP.
Parameter
| Parameter | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
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
Verwalte eine bestehende Anzeige – aktualisiere ihre Felder, ändere ihren Status oder lösche sie. Nur der Anzeigeneigentümer kann diese Aktionen durchführen. Unterstützt drei Aktionen:
Parameter
| Parameter | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
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"
}
}Rate-Limits
Der MCP-Server leitet alle Anfragen an die Owning REST API weiter, daher gelten die Rate-Limits der API:
| Werkzeug | Begrenzung | Geltungsbereich |
|---|---|---|
| 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 |
Fehlerbehandlung
Tool-Fehler werden als MCP-Ergebnisse mit isError: true und einer Fehlermeldung im Inhalt zurückgegeben:
{
"jsonrpc": "2.0",
"id": 4,
"result": {
"content": [{ "type": "text", "text": "Search failed: Rate limit exceeded (status 429)" }],
"isError": true
}
}Ungültige Argumente (Schema-Validierungsfehler) werden ebenfalls als isError-Ergebnisse mit einer Beschreibung zurückgegeben, welche Felder fehlgeschlagen sind.
Health-Check
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"
]
}Schau dir das MCP-Server-Integrationsbeispiel für eine vollständige End-to-End-Anleitung in Python und JavaScript an.