MCP 서버 빠른 시작
Owning MCP(Model Context Protocol) 서버를 사용하면 MCP 호환 AI 클라이언트 — Claude Desktop, GPT, Cursor, 또는 커스텀 에이전트 — 가 HTTP 코드 작성 없이 Owning.pro에서 등록글을 검색, 탐색, 생성, 관리할 수 있습니다. 10개의 간단한 도구를 JSON-RPC 2.0을 통해 노출합니다.
MCP 서버란?
MCP 서버는 MCP 프로토콜 요청을 Owning REST API에 대한 HTTP 호출로 변환하는 얇은 레이어입니다. 헤더, URL, JSON 본문으로 HTTP 요청을 구성하는 대신, AI 에이전트는 단순히 다음과 같은 도구를 호출합니다: search_listings 또는 create_listing 구조화된 인수와 함께.
에이전트에게 더 간단 — 도구에 타입된 매개변수와 설명이 있어 LLM이 무엇을 전달해야 하는지 정확히 압니다.
HTTP 보일러플레이트 없음 — 서버가 인증 헤더, URL 구성, 응답 파싱을 처리합니다.
구조화된 결과 — 결과는 LLM이 추론할 준비가 된 텍스트 콘텐츠(JSON 또는 Markdown)로 반환됩니다.
아키텍처
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)MCP 서버에 연결
서버 URL
| 엔드포인트 | 메서드 | 용도 |
|---|---|---|
https://mcp.owning.pro/mcp | POST | JSON-RPC 2.0 요청 → 응답 |
https://mcp.owning.pro/mcp/sse | GET | SSE 킵얼라이브 (SSE를 기대하는 클라이언트용) |
https://mcp.owning.pro/health | GET | 헬스 체크 + 도구 목록 |
프로토콜
서버는 MCP Streamable HTTP 전송(사양 2025-03-26)을 구현합니다. 각 POST /mcp 요청은 완전한 JSON-RPC 2.0 요청 → 응답 주기입니다. 영구 연결이 필요하지 않습니다.
인증
Owning API 키를 Authorization 헤더의 Bearer 토큰으로 전달하세요:
Authorization: Bearer own_aBcD123eFgH456iJkL789mNoP012qRsT345uVwX678yZ- 읽기 도구(검색, 가져오기, 카테고리, 자산 유형) — API 키 선택. 키 없이 요청은 익명입니다(공개 속도 제한: IP당 100 req/min).
- 쓰기 도구(생성, 업로드, 게시, 관리) — 쓰기 권한이 있는 API 키 필요.
- contact_seller — API 키 선택(공개 엔드포인트, IP당 속도 제한).
1단계: 초기화
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" }
}
}2단계: 사용 가능한 도구 목록
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 inputSchema3단계: 도구 호출
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\": {...} }" }]
}
}읽기 도구 (5)
등록글 검색 및 탐색용 읽기 전용 도구. API 키는 선택 — 없으면 익명 요청.
1. search_listings
필터로 등록글 검색. 제목, 가격, 위치, 이미지, 주요 속성과 함께 일치하는 등록글 반환.
매개변수
| 매개변수 | 타입 | 필수 | 기본값 | 설명 |
|---|---|---|---|---|
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
ID 또는 슬러그로 특정 등록글의 전체 상세 정보 가져오기. 설명, 사양, 모든 이미지, 가격, 위치, 속성을 포함한 모든 사용 가능한 정보 반환.
매개변수
| 매개변수 | 타입 | 필수 | 설명 |
|---|---|---|---|
id_or_slug | string | Yes | Listing ID (ULID) or slug (e.g. azimut-95-magellano-2024) |
3. get_listing_markdown
Markdown 형식으로 등록글 가져오기 — 에이전트 및 AI 소비에 최적화. YAML 프론트매터가 있는 구조화된 Markdown 문서에 모든 등록글 데이터(제목, 가격, 설명, 사양, 이미지, 속성) 포함.
매개변수
| 매개변수 | 타입 | 필수 | 설명 |
|---|---|---|---|
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
Owning.pro의 모든 사용 가능한 카테고리와 등록글 수 나열. 슬러그 이름과 항목 수가 있는 카테고리 계층 트리(상위 및 하위 카테고리) 반환. 매개변수 불필요.
5. get_asset_type
특정 카테고리의 속성 템플릿 가져오기. 해당 카테고리의 등록글에 사용 가능한 필드/속성 표시(예: 보트의 브랜드, 모델, 연식, 길이).
매개변수
| 매개변수 | 타입 | 필수 | 설명 |
|---|---|---|---|
category | string | Yes | Category slug / asset type ID (e.g. boats, cars) |
쓰기 도구 (5)
등록글 생성, 게시, 관리용 쓰기 도구. contact_seller(공개)를 제외하고 모두 쓰기 권한이 있는 API 키 필요.
6. create_listing
Owning.pro에 새 등록글 생성. 등록글은 임시 상태로 생성 — publish_listing으로 공개 표시. 속도 제한: 사용자당 하루 10개 등록글.
매개변수
| 매개변수 | 타입 | 필수 | 설명 |
|---|---|---|---|
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
Owning.pro에 이미지 업로드. base64 인코딩 데이터로 이미지 전달. listing_id가 제공되면 해당 등록글에 첨부(소유권 필요). 생략하면 독립 업로드가 create_listing에 사용할 URL 반환. 속도 제한: 하루 50개 이미지. 지원 포맷: jpg, png, webp, heic, heif, avif. 최대 크기: 10 MB.
매개변수
| 매개변수 | 타입 | 필수 | 설명 |
|---|---|---|---|
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
임시 등록글을 게시하여 Owning.pro에 공개 표시. 등록글을 임시에서 판매 중 상태로 이동. 등록글 소유자만 게시 가능.
매개변수
| 매개변수 | 타입 | 필수 | 설명 |
|---|---|---|---|
id_or_slug | string | Yes | Listing ID or slug of the draft listing to publish |
9. contact_seller
메시지를 보내 등록글 판매자에게 연락. 판매자의 이메일은 노출되지 않음 — API가 이메일로 메시지를 중계하고 판매자가 회신 가능. API 키 불필요(공개 엔드포인트). 속도 제한: IP당 시간당 5회.
매개변수
| 매개변수 | 타입 | 필수 | 설명 |
|---|---|---|---|
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
기존 등록글 관리 — 필드 업데이트, 상태 변경, 또는 삭제. 등록글 소유자만 수행 가능. 세 가지 작업 지원:
매개변수
| 매개변수 | 타입 | 필수 | 설명 |
|---|---|---|---|
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"
}
}속도 제한
MCP 서버는 모든 요청을 Owning REST API로 전달하므로 API의 속도 제한이 적용됩니다:
| 도구 | 제한 | 범위 |
|---|---|---|
| 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 |
오류 처리
도구 오류는 isError: true와 콘텐츠의 오류 메시지로 MCP 결과로 반환됩니다:
{
"jsonrpc": "2.0",
"id": 4,
"result": {
"content": [{ "type": "text", "text": "Search failed: Rate limit exceeded (status 429)" }],
"isError": true
}
}잘못된 인수(스키마 검증 실패)도 어떤 필드가 실패했는지 설명과 함께 isError 결과로 반환됩니다.
헬스 체크
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"
]
}확인해 보세요: MCP 서버 통합 예제 Python과 JavaScript의 완전한 엔드투엔드 워크스루.