evimnet-mcp 1.0.0 → 1.1.0
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.
- package/DIZIN-KAYIT.md +64 -0
- package/package.json +1 -1
- package/server.js +6 -4
- package/tools/agent.js +86 -88
package/DIZIN-KAYIT.md
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# MCP Dizin Kayıt Bilgileri
|
|
2
|
+
|
|
3
|
+
Aşağıdaki bilgileri kopyala-yapıştır ile ilgili sitelere gir.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Smithery.ai (en kolay, anında yayınlanır)
|
|
8
|
+
|
|
9
|
+
**URL:** https://smithery.ai/new
|
|
10
|
+
|
|
11
|
+
| Alan | Değer |
|
|
12
|
+
|------|-------|
|
|
13
|
+
| Server Name | evimnet-mcp |
|
|
14
|
+
| Display Name | Evimnet — Turkey Real Estate Search |
|
|
15
|
+
| GitHub URL | https://github.com/high5emlak/evimnetglobal/tree/main/mcp-server |
|
|
16
|
+
| npm Package | evimnet-mcp |
|
|
17
|
+
| Description (EN) | Search properties for sale and rent across Turkey. Covers Istanbul, Bodrum, Antalya, Izmir and all cities. Includes currency conversion (TRY/EUR/USD), area info (schools, hospitals, transport), and market statistics. 9 tools for AI assistants. |
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## 2. mcp.so
|
|
22
|
+
|
|
23
|
+
**URL:** https://mcp.so/ → Submit butonu
|
|
24
|
+
|
|
25
|
+
| Alan | Değer |
|
|
26
|
+
|------|-------|
|
|
27
|
+
| Name | Evimnet MCP |
|
|
28
|
+
| Description | Turkey's real estate search for AI assistants. Search sale/rent properties, get property details, area info (POIs, weather, AQI), currency rates (TRY/EUR/USD), and platform stats. Supports Turkish, German, and English. |
|
|
29
|
+
| GitHub | https://github.com/high5emlak/evimnetglobal/tree/main/mcp-server |
|
|
30
|
+
| npm | https://www.npmjs.com/package/evimnet-mcp |
|
|
31
|
+
| Install command | npx evimnet-mcp |
|
|
32
|
+
| Category | Real Estate / Property |
|
|
33
|
+
| Tools count | 9 |
|
|
34
|
+
| Tools | search_properties, get_property_details, get_locations, search_location, get_area_info, send_inquiry, get_currency_rates, get_platform_stats, convert_price |
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## 3. Glama.ai
|
|
39
|
+
|
|
40
|
+
**URL:** https://glama.ai/mcp/servers → Add Server
|
|
41
|
+
|
|
42
|
+
| Alan | Değer |
|
|
43
|
+
|------|-------|
|
|
44
|
+
| GitHub Repository URL | https://github.com/high5emlak/evimnetglobal |
|
|
45
|
+
| Server path | mcp-server/ |
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Ortak bilgiler (her yerde kullanılabilir)
|
|
50
|
+
|
|
51
|
+
**Kısa açıklama (TR):**
|
|
52
|
+
Türkiye'de satılık ve kiralık emlak arama. İstanbul, Bodrum, Antalya, İzmir ve tüm şehirler. Döviz çevirimi, çevre bilgisi, piyasa istatistikleri. 9 AI aracı.
|
|
53
|
+
|
|
54
|
+
**Kısa açıklama (EN):**
|
|
55
|
+
Search properties for sale and rent across Turkey. Istanbul, Bodrum, Antalya, Izmir and all cities. Currency conversion, area info, market stats. 9 AI tools.
|
|
56
|
+
|
|
57
|
+
**Kısa açıklama (DE):**
|
|
58
|
+
Immobiliensuche in der Türkei — Kauf und Miete. Istanbul, Bodrum, Antalya, Izmir und alle Städte. Währungsumrechnung, Umgebungsinfos, Marktstatistiken. 9 KI-Tools.
|
|
59
|
+
|
|
60
|
+
**Tags:** real-estate, turkey, property, mcp, ai, bodrum, istanbul, antalya, rental, sale
|
|
61
|
+
|
|
62
|
+
**Website:** https://evimnet.com
|
|
63
|
+
**npm:** https://www.npmjs.com/package/evimnet-mcp
|
|
64
|
+
**License:** MIT
|
package/package.json
CHANGED
package/server.js
CHANGED
|
@@ -60,10 +60,12 @@ const TOOL_HANDLERS = {
|
|
|
60
60
|
convert_price: (a) => handleMarketTool('convert_price', a),
|
|
61
61
|
|
|
62
62
|
// Emlakçı araçları (API key gerekli)
|
|
63
|
-
get_my_leads:
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
63
|
+
get_my_leads: (a) => handleAgentTool('get_my_leads', a),
|
|
64
|
+
get_lead_detail: (a) => handleAgentTool('get_lead_detail', a),
|
|
65
|
+
update_lead_status: (a) => handleAgentTool('update_lead_status', a),
|
|
66
|
+
get_my_listings: (a) => handleAgentTool('get_my_listings', a),
|
|
67
|
+
get_listing_analytics: (a) => handleAgentTool('get_listing_analytics', a),
|
|
68
|
+
get_my_stats: (a) => handleAgentTool('get_my_stats', a),
|
|
67
69
|
};
|
|
68
70
|
|
|
69
71
|
// ─── Server oluştur ──────────────────────────────────────────────────────────
|
package/tools/agent.js
CHANGED
|
@@ -30,12 +30,23 @@ Filtreleme: durum (NEW=Yeni, CONTACTED=Arandı, MEETING=Görüşme, CLOSED=Kapan
|
|
|
30
30
|
enum: ['NEW', 'CONTACTED', 'MEETING', 'CLOSED'],
|
|
31
31
|
description: 'Durum filtresi (boş = hepsi)',
|
|
32
32
|
},
|
|
33
|
-
page: { type: 'number', description: 'Sayfa numarası (varsayılan: 1)' },
|
|
34
|
-
limit: { type: 'number', description: 'Sayfa başı kayıt (maks: 50, varsayılan: 20)' },
|
|
35
33
|
},
|
|
36
34
|
},
|
|
37
35
|
},
|
|
38
36
|
|
|
37
|
+
{
|
|
38
|
+
name: 'get_lead_detail',
|
|
39
|
+
description: `Tek bir lead'in detayını getir. İlan bilgisi, mesaj ve iletişim bilgileri dahil.
|
|
40
|
+
Örnek: "Ahmet Yılmaz'ın başvuru detayını göster"`,
|
|
41
|
+
inputSchema: {
|
|
42
|
+
type: 'object',
|
|
43
|
+
properties: {
|
|
44
|
+
id: { type: 'string', description: 'Lead ID (get_my_leads\'ten alınır)' },
|
|
45
|
+
},
|
|
46
|
+
required: ['id'],
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
|
|
39
50
|
{
|
|
40
51
|
name: 'update_lead_status',
|
|
41
52
|
description: `Lead durumunu güncelle.
|
|
@@ -43,40 +54,50 @@ Filtreleme: durum (NEW=Yeni, CONTACTED=Arandı, MEETING=Görüşme, CLOSED=Kapan
|
|
|
43
54
|
inputSchema: {
|
|
44
55
|
type: 'object',
|
|
45
56
|
properties: {
|
|
46
|
-
|
|
57
|
+
id: { type: 'string', description: 'Lead ID' },
|
|
47
58
|
status: {
|
|
48
59
|
type: 'string',
|
|
49
60
|
enum: ['NEW', 'CONTACTED', 'MEETING', 'CLOSED'],
|
|
50
61
|
description: 'Yeni durum',
|
|
51
62
|
},
|
|
52
63
|
},
|
|
53
|
-
required: ['
|
|
64
|
+
required: ['id', 'status'],
|
|
54
65
|
},
|
|
55
66
|
},
|
|
56
67
|
|
|
57
68
|
{
|
|
58
69
|
name: 'get_my_listings',
|
|
59
|
-
description: `Emlakçının ilanlarını getir.
|
|
60
|
-
Aktif, taslak, pasif ilanlar. Lead sayısı ve görüntülenme bilgisi dahil.
|
|
70
|
+
description: `Emlakçının ilanlarını getir. Görüntülenme ve favori sayıları dahil.
|
|
61
71
|
Örnek: "Aktif ilanlarımı listele", "Taslak ilanlarım var mı?"`,
|
|
62
72
|
inputSchema: {
|
|
63
73
|
type: 'object',
|
|
64
74
|
properties: {
|
|
65
75
|
status: {
|
|
66
76
|
type: 'string',
|
|
67
|
-
enum: ['DRAFT', 'PENDING', 'APPROVED', 'PASSIVE'
|
|
77
|
+
enum: ['DRAFT', 'PENDING', 'APPROVED', 'PASSIVE'],
|
|
68
78
|
description: 'Durum filtresi (boş = hepsi)',
|
|
69
79
|
},
|
|
70
|
-
page: { type: 'number', description: 'Sayfa numarası' },
|
|
71
|
-
limit: { type: 'number', description: 'Sayfa başı kayıt' },
|
|
72
80
|
},
|
|
73
81
|
},
|
|
74
82
|
},
|
|
75
83
|
|
|
84
|
+
{
|
|
85
|
+
name: 'get_listing_analytics',
|
|
86
|
+
description: `Bir ilanın performans analitiğini getir: görüntülenme, tıklama, Avrupa görüntülenme, lead sayısı, boost durumu.
|
|
87
|
+
Örnek: "Yalıkavak villamın performansı nasıl?"`,
|
|
88
|
+
inputSchema: {
|
|
89
|
+
type: 'object',
|
|
90
|
+
properties: {
|
|
91
|
+
id: { type: 'string', description: 'İlan ID (get_my_listings\'ten alınır)' },
|
|
92
|
+
},
|
|
93
|
+
required: ['id'],
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
|
|
76
97
|
{
|
|
77
98
|
name: 'get_my_stats',
|
|
78
99
|
description: `Dashboard özeti: aktif ilan sayısı, yeni lead sayısı, toplam görüntülenme.
|
|
79
|
-
Örnek: "Durumumu özetle", "
|
|
100
|
+
Örnek: "Durumumu özetle", "Genel performansım nasıl?"`,
|
|
80
101
|
inputSchema: {
|
|
81
102
|
type: 'object',
|
|
82
103
|
properties: {},
|
|
@@ -85,95 +106,72 @@ Aktif, taslak, pasif ilanlar. Lead sayısı ve görüntülenme bilgisi dahil.
|
|
|
85
106
|
];
|
|
86
107
|
|
|
87
108
|
export async function handleAgentTool(name, args) {
|
|
88
|
-
if (name === 'get_my_leads')
|
|
89
|
-
if (name === '
|
|
90
|
-
if (name === '
|
|
91
|
-
if (name === '
|
|
109
|
+
if (name === 'get_my_leads') return getMyLeads(args);
|
|
110
|
+
if (name === 'get_lead_detail') return getLeadDetail(args);
|
|
111
|
+
if (name === 'update_lead_status') return updateLeadStatus(args);
|
|
112
|
+
if (name === 'get_my_listings') return getMyListings(args);
|
|
113
|
+
if (name === 'get_listing_analytics') return getListingAnalytics(args);
|
|
114
|
+
if (name === 'get_my_stats') return getMyStats();
|
|
92
115
|
}
|
|
93
116
|
|
|
94
|
-
async function
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
const leads = data.leads.map(l => ({
|
|
103
|
-
id: l.id,
|
|
104
|
-
name: l.name,
|
|
105
|
-
email: l.email,
|
|
106
|
-
phone: l.phone || null,
|
|
107
|
-
status: l.status,
|
|
108
|
-
message: l.message || null,
|
|
109
|
-
listing: l.listing ? { title: l.listing.title, slug: l.listing.slug, price: `${l.listing.priceTRY?.toLocaleString('tr-TR')} ₺` } : null,
|
|
110
|
-
createdAt: l.createdAt,
|
|
111
|
-
}));
|
|
112
|
-
|
|
113
|
-
return {
|
|
114
|
-
content: [{
|
|
115
|
-
type: 'text',
|
|
116
|
-
text: JSON.stringify({ leads, total: data.total, page: data.page }, null, 2),
|
|
117
|
-
}],
|
|
118
|
-
};
|
|
117
|
+
async function mcpGet(action, params = {}) {
|
|
118
|
+
const qs = new URLSearchParams({ action, ...params });
|
|
119
|
+
const res = await fetch(`${BASE_URL}/api/mcp/agent?${qs}`, { headers: agentHeaders() });
|
|
120
|
+
if (!res.ok) {
|
|
121
|
+
const body = await res.json().catch(() => ({}));
|
|
122
|
+
throw new Error(body.error || `API hatası: ${res.status}`);
|
|
123
|
+
}
|
|
124
|
+
return res.json();
|
|
119
125
|
}
|
|
120
126
|
|
|
121
|
-
async function
|
|
122
|
-
const
|
|
123
|
-
|
|
127
|
+
async function mcpPatch(action, body) {
|
|
128
|
+
const qs = new URLSearchParams({ action });
|
|
129
|
+
const res = await fetch(`${BASE_URL}/api/mcp/agent?${qs}`, {
|
|
130
|
+
method: 'PATCH',
|
|
124
131
|
headers: agentHeaders(),
|
|
125
|
-
body:
|
|
132
|
+
body: JSON.stringify(body),
|
|
126
133
|
});
|
|
127
|
-
if (!res.ok)
|
|
134
|
+
if (!res.ok) {
|
|
135
|
+
const data = await res.json().catch(() => ({}));
|
|
136
|
+
throw new Error(data.error || `API hatası: ${res.status}`);
|
|
137
|
+
}
|
|
138
|
+
return res.json();
|
|
139
|
+
}
|
|
128
140
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
type: 'text',
|
|
132
|
-
text: JSON.stringify({ success: true, leadId, status }, null, 2),
|
|
133
|
-
}],
|
|
134
|
-
};
|
|
141
|
+
function textResult(data) {
|
|
142
|
+
return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
|
|
135
143
|
}
|
|
136
144
|
|
|
137
|
-
async function
|
|
138
|
-
const params =
|
|
139
|
-
if (status) params.
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
const data = await res.json();
|
|
144
|
-
|
|
145
|
-
const listings = data.listings.map(l => ({
|
|
146
|
-
id: l.id,
|
|
147
|
-
title: l.title,
|
|
148
|
-
slug: l.slug,
|
|
149
|
-
type: l.type,
|
|
150
|
-
status: l.status,
|
|
151
|
-
price: `${l.priceTRY?.toLocaleString('tr-TR')} ₺`,
|
|
152
|
-
sqm: l.sqmNet ? `${l.sqmNet}m²` : null,
|
|
153
|
-
rooms: l.rooms || null,
|
|
154
|
-
city: l.city?.name || null,
|
|
155
|
-
district: l.district?.name || null,
|
|
156
|
-
leads: l._count?.leads || 0,
|
|
157
|
-
url: `https://evimnet.com/ilan/${l.slug}`,
|
|
158
|
-
}));
|
|
145
|
+
async function getMyLeads({ status } = {}) {
|
|
146
|
+
const params = {};
|
|
147
|
+
if (status) params.status = status;
|
|
148
|
+
const data = await mcpGet('leads', params);
|
|
149
|
+
return textResult(data);
|
|
150
|
+
}
|
|
159
151
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
text: JSON.stringify({ listings, total: data.total }, null, 2),
|
|
164
|
-
}],
|
|
165
|
-
};
|
|
152
|
+
async function getLeadDetail({ id }) {
|
|
153
|
+
const data = await mcpGet('lead', { id });
|
|
154
|
+
return textResult(data);
|
|
166
155
|
}
|
|
167
156
|
|
|
168
|
-
async function
|
|
169
|
-
const
|
|
170
|
-
|
|
171
|
-
|
|
157
|
+
async function updateLeadStatus({ id, status }) {
|
|
158
|
+
const data = await mcpPatch('lead-status', { id, status });
|
|
159
|
+
return textResult(data);
|
|
160
|
+
}
|
|
172
161
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
162
|
+
async function getMyListings({ status } = {}) {
|
|
163
|
+
const params = {};
|
|
164
|
+
if (status) params.status = status;
|
|
165
|
+
const data = await mcpGet('listings', params);
|
|
166
|
+
return textResult(data);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
async function getListingAnalytics({ id }) {
|
|
170
|
+
const data = await mcpGet('analytics', { id });
|
|
171
|
+
return textResult(data);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
async function getMyStats() {
|
|
175
|
+
const data = await mcpGet('stats');
|
|
176
|
+
return textResult(data);
|
|
179
177
|
}
|