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 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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "evimnet-mcp",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Evimnet MCP Server — AI asistanlar için Türkiye gayrimenkul araçları",
5
5
  "type": "module",
6
6
  "bin": {
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: (a) => handleAgentTool('get_my_leads', a),
64
- update_lead_status: (a) => handleAgentTool('update_lead_status', a),
65
- get_my_listings: (a) => handleAgentTool('get_my_listings', a),
66
- get_my_stats: (a) => handleAgentTool('get_my_stats', a),
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
- leadId: { type: 'string', description: 'Lead ID (get_my_leads\'ten alınır)' },
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: ['leadId', 'status'],
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', 'SOLD', 'RENTED', 'REJECTED'],
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", "Bu hafta kaç kişi ilanlarımı gördü?"`,
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') return getMyLeads(args);
89
- if (name === 'update_lead_status') return updateLeadStatus(args);
90
- if (name === 'get_my_listings') return getMyListings(args);
91
- if (name === 'get_my_stats') return getMyStats();
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 getMyLeads({ status, page = 1, limit = 20 } = {}) {
95
- const params = new URLSearchParams({ page: String(page), limit: String(limit) });
96
- if (status) params.set('status', status);
97
-
98
- const res = await fetch(`${BASE_URL}/api/mcp/leads?${params}`, { headers: agentHeaders() });
99
- if (!res.ok) throw new Error(`API hatası: ${res.status}`);
100
- const data = await res.json();
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 updateLeadStatus({ leadId, status }) {
122
- const res = await fetch(`${BASE_URL}/api/mcp/leads/${leadId}`, {
123
- method: 'PATCH',
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: JSON.stringify({ status }),
132
+ body: JSON.stringify(body),
126
133
  });
127
- if (!res.ok) throw new Error(`API hatası: ${res.status}`);
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
- return {
130
- content: [{
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 getMyListings({ status, page = 1, limit = 20 } = {}) {
138
- const params = new URLSearchParams({ page: String(page), limit: String(limit) });
139
- if (status) params.set('status', status);
140
-
141
- const res = await fetch(`${BASE_URL}/api/mcp/listings?${params}`, { headers: agentHeaders() });
142
- if (!res.ok) throw new Error(`API hatası: ${res.status}`);
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
- return {
161
- content: [{
162
- type: 'text',
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 getMyStats() {
169
- const res = await fetch(`${BASE_URL}/api/mcp/stats`, { headers: agentHeaders() });
170
- if (!res.ok) throw new Error(`API hatası: ${res.status}`);
171
- const data = await res.json();
157
+ async function updateLeadStatus({ id, status }) {
158
+ const data = await mcpPatch('lead-status', { id, status });
159
+ return textResult(data);
160
+ }
172
161
 
173
- return {
174
- content: [{
175
- type: 'text',
176
- text: JSON.stringify(data, null, 2),
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
  }