Live Northern Cyprus (KKTC/TRNC) property listings and asking-price data. Read-only, 8 tools.
The app.evlek MCP server provides live property listing and asking-price data for Northern Cyprus (KKTC/TRNC). It is read-only and exposes 12 tools. The server is available via the hosted endpoint at evlek.app/api/mcp and is registered under app.evlek in the MCP Registry.
🛠️ Key Features
Live Northern Cyprus (KKTC/TRNC) property listings
Asking-price data access
Read-only behavior
12 tools exposed
🚀 Use Cases
Retrieve Northern Cyprus property listings with asking prices
Build developer workflows that consume current property data
Integrate property/proptech sources into LLM-based applications
⚡ Developer Benefits
Model Context Protocol (MCP) server for tool-based integration
Hosted deployment endpoint: evlek.app/api/mcp
Supports MCP Registry discovery (app.evlek)
⚠️ Limitations
Read-only access (no updates or write operations)
Tool surface is limited to the server’s provided tools (12 total)
Search live active sale and long-term-rent listings on Evlek. Results are newest-first by default; `limit` caps returned rows and `totalMatched` reports the full match count. Returns advertised asking-price and listing facts only; not valuation, verification of property-specific claims, forecast, ranking, or recommendation.
Parameters17
query
string
optional
Optional free-text query (parsed like the `search` tool); merges with explicit filters below — an explicit filter wins on conflict
city
string
optional
Slug, Turkish name, or exonym (Kyrenia/Nicosia/Famagusta/Morphou).
type
string
optional
Listing type
district
string
optional
District name (e.g. Alsancak), matched accent/case-insensitively against the active-listing district list
propertyType
string
optional
Raw property type (apartment, villa, …) or K75 group slug: house (villa+detached+bungalow), land, commercial
Returns source-dated aggregates of live active Evlek sale or long-term-rent asking prices. Descriptive listing facts only: not completed transactions, a valuation, a forecast, or an investment recommendation.
Parameters2
city
string
optional
Filter to a single city (omit for all cities). Slug, Turkish name, or exonym (Kyrenia/Nicosia/Famagusta/Morphou).
type
string
optional
Sale or rent (default: sale)
Raw schema
{
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "Filter to a single city (omit for all cities). Slug, Turkish name, or exonym (Kyrenia/Nicosia/Famagusta/Morphou)."
},
"type": {
"type": "string",
"enum": [
"sale",
"rent"
],
"description": "Sale or rent (default: sale)"
}
}
}
compare_cities
Compare source-dated live active-listing asking-price aggregates across 2-4 Northern Cyprus cities. Descriptive listing facts only; not transaction prices, valuation, forecast, ranking, or investment advice.
Compare descriptive facts from 2-4 active Evlek sale or long-term-rent listings of the same type. Shows advertised asking price, size and £/m² differences without making a value, suitability, appraisal, or investment judgment. The legacy `listing_ids` parameter name is still accepted as an alias of `listingIds`.
Returns source-dated active sale/long-term-rent listing counts and asking-price aggregates for one district. Any rent-to-price percentage is a derived asking-price ratio, not observed income, net yield, valuation, forecast, ranking, or recommendation.
Parameters2
city
string
required
City containing the district. Slug, Turkish name, or exonym (Kyrenia/Nicosia/Famagusta/Morphou).
district
string
required
District name (2-60 chars), matched accent/case-insensitively against the active-listing district list
Raw schema
{
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "City containing the district. Slug, Turkish name, or exonym (Kyrenia/Nicosia/Famagusta/Morphou)."
},
"district": {
"type": "string",
"description": "District name (2-60 chars), matched accent/case-insensitively against the active-listing district list"
}
},
"required": [
"city",
"district"
]
}
convert_currency
Converts an entered property asking-price amount across GBP/EUR/USD/TRY when complete, valid, fresh, date-stamped stored FX rates are available; otherwise it fails closed without amounts. Currency conversion only: no payment plan, deposit schedule, installment schedule, acquisition-cost estimate, or advice.
Parameters2
price
number
required
Entered property asking-price amount; not a deposit or installment.
currency
string
optional
Currency of the price (default GBP).
Raw schema
{
"type": "object",
"properties": {
"price": {
"type": "number",
"minimum": 1000,
"maximum": 100000000,
"description": "Entered property asking-price amount; not a deposit or installment."
},
"currency": {
"type": "string",
"enum": [
"GBP",
"EUR",
"USD",
"TRY"
],
"description": "Currency of the price (default GBP)."
}
},
"required": [
"price"
]
}
payment_plan
Currently returns currency conversion only. A real installment/payment-schedule tool is planned under this name; until then it does not produce a payment plan, deposit schedule, or acquisition-cost estimate.
Parameters2
price
number
required
Entered property asking-price amount; not a deposit or installment.
currency
string
optional
Currency of the price (default GBP).
Raw schema
{
"type": "object",
"properties": {
"price": {
"type": "number",
"minimum": 1000,
"maximum": 100000000,
"description": "Entered property asking-price amount; not a deposit or installment."
},
"currency": {
"type": "string",
"enum": [
"GBP",
"EUR",
"USD",
"TRY"
],
"description": "Currency of the price (default GBP)."
}
},
"required": [
"price"
]
}
get_listing_detail
Return a 360° profile of one active Evlek listing by UUID or listing number: title, description, price, location, size, amenities, features, cover image, per-photo captions/tags, and AI virtual-staging before/after pairs (always AI-disclosed). Contact details omitted. Use when: a UUID or listing number is already known. Don't use for: discovery — use search_listings first. The legacy `property_id` parameter name is still accepted as an alias of `propertyId`.
Parameters1
propertyId
string
required
Evlek listing UUID or listing number (e.g. "EVL-123456", "123456")
Search live Northern Cyprus (KKTC/TRNC) property listings on Evlek with a free-text query. Returns matching listings as id/title/url for the fetch tool. Same data as search_listings — this fixed form exists for the ChatGPT/OpenAI connector contract. Use when: the caller only has a free-text query. Don't use for: structured filters — use search_listings.
Fetch the full detail of one Evlek listing by id (from search): title, description, GBP-normalized price, location, size, amenities. Same data as get_listing_detail — this fixed id-only form exists for the ChatGPT/OpenAI connector contract. Use when: an id from search is known. Don't use for: discovery — use search first.
Return canonical KKTC city slugs plus districts represented by active Evlek sale or long-term-rent listings. Live inventory-location facts only; holiday-home inventory remains unavailable.
Parameters1
city
string
optional
Optional — limit districts to a single city. Slug, Turkish name, or exonym (Kyrenia/Nicosia/Famagusta/Morphou).
Raw schema
{
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "Optional — limit districts to a single city. Slug, Turkish name, or exonym (Kyrenia/Nicosia/Famagusta/Morphou)."
}
}
}
get_listing_by_number
Look up a single Evlek listing by its public listing number (e.g. "EVL-123456", "123456", or a bare number) and return its full detail — same shape as get_listing_detail. Use when: a listing number is known. Don't use for: UUID lookups — use get_listing_detail. The legacy `listing_number` parameter name is still accepted as an alias of `listingNumber`.
Parameters1
listingNumber
string | number
required
Evlek listing number, e.g. "EVL-123456", "123456", or the bare number 123456.
Raw schema
{
"type": "object",
"properties": {
"listingNumber": {
"type": [
"string",
"number"
],
"description": "Evlek listing number, e.g. \"EVL-123456\", \"123456\", or the bare number 123456."
}
},
"required": [
"listingNumber"
]
}
AI-native property discovery for North Cyprus (KKTC). Built on the Model Context Protocol — works in Claude, ChatGPT, Gemini, Cursor, and any MCP-compatible client.
The Evlek MCP server gives AI agents structured, real-time access to North Cyprus property data — search active listings, compare cities and districts, and track the price index. All data is sourced live from evlek.app. Evlek does not offer a rental-yield or investment-return estimate: figures are descriptive asking-price facts only, never a valuation, forecast, or recommendation. Title-deed (koçan) and legal-procedure tools are deliberately not part of the surface: that taxonomy has not passed an independent KKTC legal audit.
License scope
This repository is MIT-licensed for the public manifest, documentation, examples, and reference clients contained here. The hosted Evlek service, evlek.app web app, mobile apps, listing database, AI prompts, business logic, brand assets, name, logo, and trade dress remain proprietary and are not licensed under MIT. See LICENSE for details.
Why Evlek MCP
AI-first. Built for agentic workflows from day one — not retrofitted on a legacy listing API.
Multilingual. Answers in TR, EN, RU, DE, AR: pass locale (or write the search query in that language) and the text, amenity names, number formats and links follow it. Place names are resolved in any of the five languages.
Verification-aware listings. Evlek surfaces listing and account verification context where available, and the MCP omits contact fields to preserve Evlek's reveal/contact funnel.
Built for the region. Optimized for the 6 cities of North Cyprus (Lefkoşa, Girne, Gazimağusa, İskele, Güzelyurt, Lefke) and 100+ districts.
Add https://evlek.app/api/mcp as a custom connector. Evlek exposes OpenAI-compatible search and fetch tools, so it works in ChatGPT connectors and Deep Research in addition to developer mode.
Claude Desktop (legacy stdio bridge)
If your client only supports stdio servers, use the pinned mcp-remote bridge. Add this to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):
This repo is also a runnable MCP server. It answers initialize / tools/list entirely locally from the embedded tool contract (tools.json) and fetches live data from the Evlek data API when a tool is called. It only implements tools — it does not declare the resources or prompts capability, so resources/list and prompts/list return a normal MCP "method not found" error on this bridge; those primitives (see below) are hosted-endpoint-only, reachable via the Streamable HTTP URL above. It also speaks whatever MCP protocol version the pinned @modelcontextprotocol/sdk supports during initialize (currently 2025-11-25), not necessarily the hosted endpoint's 2026-07-28 — tool schemas are identical either way.
Use this when the user wants to find or see property listings; results are shown with real photos in the Evlek widget. Search live Evlek property listings for sale and long-term rent in Northern Cyprus (KKTC/TRNC; prices in GBP unless a currency is given; 2+1 means bedrooms 2) with structured filters: transaction, city, district, property type, bedrooms, price, areas, amenities, nearby university. Pass the user's language as locale (tr|en|ru|de|ar): the text, amenity names, number formats and links follow it. Returns at most 10 listings per call, each as one readable line (type, place, price, rooms, area, a deterministic sentence, data notes, canonical link) plus a structured card; continue with the nextCursor of a group. Without transaction, listings for sale and for rent come as two separate groups, each with its own cursor that is only valid together with that group's transaction. Place names in any language are resolved; an unknown place returns suggestions instead of results. An amenity that cannot be filtered on is reported as not applied. For one listing use get_listing. Returns advertised asking-price and listing facts only: not a valuation, verification of property-specific claims, forecast, ranking or recommendation.
search
Search Evlek property listings
Use only for research and citation lookups (deep research). To show listings to the user, use search_listings instead. Search live Northern Cyprus (KKTC/TRNC) property listings on Evlek with a free-text query in Turkish, English, Russian, German or Arabic. Returns matching listings as id/title/url for the fetch tool, newest first (sale and rent as two groups when the query names neither). The answer language follows the language of the query. Same data as search_listings: this fixed form exists for the ChatGPT/OpenAI connector contract. Use when: the caller only has a free-text query ("2+1 apartment in Kyrenia under 150000 pounds", "EVL-100464"). Don't use for: structured filters, paging or another answer language: use search_listings.
fetch
Fetch full Evlek listing detail
Fetch the full detail of one Evlek listing: title, price, location, rooms, areas, amenities, data-quality notes and the canonical link. The id is the listing id (UUID) from a search result, a listing number such as EVL-100464, or an evlek.app listing link; the answer language follows the link (English otherwise). A listing that is not available (it does not exist, is not public, or was removed) always gets the same answer. Same data as get_listing: this fixed id-only form exists for the ChatGPT/OpenAI connector contract. Use when: an id from search is known. Don't use for: discovery (use search first) or another answer language (use get_listing).
get_listing
Get an Evlek listing
Get the full details of ONE public Evlek listing (sale or long-term rent) in the user's language. ref is the listing id (UUID), the listing number (EVL-100464 or just 100464) or an evlek.app listing link in any language. Returns the price, rooms, bathrooms, built area and plot area (always separate), the approximate location, features, the office name, dates, data-quality notes, photos with captions where they exist, AI virtual-staging before/after images when the office approved them (always labelled as AI-generated) and the canonical link. Contact details are never included: send the user to the link. A listing that is unknown or no longer public answers found:false with code NOT_FOUND (this is not an error). Pass the user's language as locale (tr, en, ru, de or ar).
compare_listings
Compare Evlek listings
Compare 2 to 4 public Evlek listings side by side in the user's language: price, price per m² (only when the built area is believable), rooms, bathrooms, built area and plot area (always separate), location, furnishing, key features and data-quality notes, plus a few descriptive highlights (lowest price, largest indoor area, most recently listed). ids takes listing ids (UUID), listing numbers (EVL-100464) or evlek.app listing links, in any mix; the order you give is kept. Sale and rent listings are never ranked against each other: a mixed request is shown in two groups with a warning. A reference that is unknown or no longer public is listed in missingIds with code NOT_FOUND (this is not an error). Descriptive facts only: no valuation and no recommendation. Pass the user's language as locale (tr, en, ru, de or ar).
market_stats
Northern Cyprus market statistics
Market statistics for Northern Cyprus from asking prices of active public listings (not sales, valuations or forecasts). No city = the island by city; one city = its districts; several = side by side; city + district = a district profile. Sale and rent are reported separately. Each figure has activeCount (public listings in scope) and sampleCount (the cleaned sample behind the statistic); below 10 sampled listings it is withheld. Pass locale.
list_locations
List Evlek locations
List the places Evlek knows in Northern Cyprus (6 cities, districts, villages, sub-areas, landmarks, the Karpaz region) with their public sale and long-term rent listing counts. Call it first when unsure how a place is spelled: every name and id returned is accepted by the other tools. Pass city (any spelling or language) for one place in detail. Names are Turkish or Latin; Russian, German and Arabic spellings are accepted as input but not listed.
convert_currency
Currency conversion (GBP/EUR/USD/TRY)
Converts an amount between GBP, EUR, USD and TRY with the exchange rates Evlek stores (refreshed daily) and returns all four equivalents. Currency conversion only: no payment plan, deposit or instalment schedule, tax, fee or acquisition-cost estimate, no advice. Rates older than 24 hours are flagged as stale; beyond 72 hours (or when none are stored) no conversion is produced (FX_UNAVAILABLE).
Every tool declares annotations: { readOnlyHint: true, destructiveHint: false, openWorldHint: false } — the whole surface is read-only.
Interactive widgets (MCP Apps / SEP-1865)
Five tools additionally bind a sandboxed HTML view (_meta.ui.resourceUri) that
MCP Apps-capable hosts (Claude web/desktop) render inline in the conversation:
Tool
Widget
What you get
search_listings, search
ui://evlek/listing-cards-v3-5.html
Listing cards (cover photo, price, location); opening one shows the listing detail view; in ChatGPT, "Show on map" opens a full-screen map of every match
get_listing, fetch
ui://evlek/listing-detail-v3-5.html
Photo gallery, spec sheet, and AI virtual-staging before/after (always AI-disclosed)
market_stats
ui://evlek/price-index-v3-4.html
Asking-price statistics per city / district
compare_listings, list_locations and convert_currency have no widget. The
widget URIs moved from -v2 to -v3 in 3.0.0 so a host never serves a cached
v2 template against v3 data. 3.0.1 moved them to -v3-1, 3.0.2 to -v3-2, 3.0.3 to -v3-3 and 3.1.0 to -v3-4
(cards and detail then -v3-5); the older v3 URIs keep answering with the current content. Rule since 3.1.0: a widget's
content never changes under a URI it was published with (a host caches a template by URI), so a changed widget gets a new URI.
In ChatGPT (3.0.2, search since 3.0.3) the listing data reaches the widget through the result _meta["evlek/widget"],
which ChatGPT shows only to the widget; for search_listings and get_listing the model gets a short summary (counts, price range,
listing numbers). Other clients get the full structuredContent as before.
Views are static, self-contained HTML — no bundler, no third-party JS. Listing
data reaches them only at runtime over postMessage and is written with
textContent, never innerHTML. CSP is declared per resource
(_meta.ui.csp) and limited to the public listing-photo origin.
See TOOLS.md for full input schemas, parameter details, and response examples.
Resources (12) & resource templates (2)
resources/list returns 12 resources on the hosted endpoint — 9 read-only evlek:// data resources plus the 3 ui:// interactive-widget resources described above (pre-declared so a host can pre-cache them). Parameterized templates are separate, via resources/templates/list:
Data resources (9): per-city price indexes (girne, iskele, lefkosa, gazimagusa, guzelyurt, lefke), a sample district profile (Girne/Alsancak), and 2 orientation guides — evlek://guides/neighborhood-personas, evlek://guides/universities.
Widget resources (3):ui://evlek/listing-cards-v3-5.html, ui://evlek/listing-detail-v3-5.html, ui://evlek/price-index-v3-4.html — see "Interactive widgets" above.
Renamed tools in 3.0.0 (deprecated aliases)
3.0.0 consolidates the 12 v2 tools into 8. The old names below are not in
tools/list any more, but the hosted endpoint still answers them for one
release: the call is translated to the new tool, runs it, and the result starts
with a Deprecated: … Use <new> instead. line (plus
structuredContent.deprecated). The aliases are removed in 3.1.0 — switch
to the new names now.
Old name (v2)
New name (3.0.0)
Argument change
get_listing_detail
get_listing
propertyId / property_id → ref
get_listing_by_number
get_listing
listingNumber / listing_number → ref
compare_properties
compare_listings
listingIds / listing_ids → ids
get_price_index
market_stats
city kept; type → transaction (default sale)
compare_cities
market_stats
cities → city; type → transaction (default sale)
get_district_profile
market_stats
city, district kept
payment_plan
convert_currency
price → amount (name stays reserved for a future instalment tool)
Unchanged names: search_listings, search, fetch, list_locations,
convert_currency. search_listings, list_locations and convert_currency
gained new parameters and canonical names (e.g. transaction, priceMin/priceMax,
sort, cursor, amount, locale) — see TOOLS.md. The v2 names
type, maxPrice and price are still accepted on the hosted endpoint.
Tools removed in 2.0.0 and earlier (get_yield_estimate, suggest_neighborhood,
student_housing, get_market_overview, get_legal_info) still return a
protocol error naming the replacement, not an alias.
Prompts (2)
property_scenario — Illustrative Property Scenario with Separate Live Facts
Currency: GBP primary; TRY/USD/EUR normalized to GBP server-side using live daily exchange rates
Tool descriptions: EN · Answers: TR · EN · RU · DE · AR (locale)
Architecture
The Evlek MCP server runs as a hosted endpoint at https://evlek.app/api/mcp. It speaks the Model Context Protocol over Streamable HTTP (JSON-RPC 2.0), protocolVersion 2026-07-28, and exposes tools, resources, resource templates, and prompts. Discovery metadata is published at /.well-known/mcp.json.
tools.json — Live tool contract (what the local stdio server answers tools/list with)
TOOLS.md — Full tool reference (JSON schemas + examples)
CHANGELOG.md — Notable changes to the tool surface, including removed/renamed tools
examples/ — Configuration files for Claude Desktop, Cursor, VS Code
CONTRIBUTING.md — How to file issues and propose docs improvements
Sözleşme dosyaları (contract files)
tools.json and TOOLS.md are a projection of the live server, generated by pnpm mcp:export-public in the source repo and copied here verbatim. Never hand-edit them; the Contract Drift workflow compares tools.json against the live tools/list daily and on every PR.
server.json is not that projection. It is the MCP Registry publish manifest and must keep the registry shape: name is app.evlek/mcp-server (pattern ^[a-zA-Z0-9.-]+/[a-zA-Z0-9._-]+$) and description is at most 100 characters. A sync only updates its version, the tool count in description, and the _meta tool list. (Copying the export's own server.json here is what failed the v2.1.0 registry publish.)
The full server implementation (database schemas, API routes, AI prompt engineering, listing pipeline) is hosted at evlek.app and remains proprietary.
Security model
Per OWASP MCP Top 10: per-IP rate limit 60/min, global 500/min, 30s hard timeout, Zod input validation, output sanitization (prompt-injection defense), max 10 results per query, Supabase anon key + RLS, no stack traces leaked, Sentry observability.
MIT — see LICENSE. MIT covers the public manifest, documentation, examples, and reference clients in this repository only (see License scope above). The hosted Evlek service (web app, mobile apps, listing data, AI prompts, database schemas, business logic) is proprietary.
Trademark notice: "Evlek" is a trademark of Onur Dokuzoğlu. The MIT license does not grant rights to use the "Evlek" name, logo, or branding except as described in this README. To request brand usage permission, contact hello@evlek.app.