Skip to main content
Glama
gca-ltd

Qobrix CRM MCP Server

by gca-ltd

Содержание


Что он делает

ИИ-ассистент, подключённый к этому серверу, может просматривать объекты недвижимости, квалифицировать лидов, отслеживать показы, просматривать предложения и договоры, аудировать последующую активность и обнаруживать схемы полей CRM — всё это через естественный язык. Каждое описание инструмента обучает LLM, к какому каноническому рабочему процессу в сфере недвижимости он относится, какому ресурсу RESO соответствует и какие инструменты следует вызывать следующими.

Для кого это

  • Брокерские компании и разработчики, использующие Qobrix, которые хотят, чтобы Claude.ai, Dust.tt, ChatGPT или Cursor отвечали на вопросы на основе живых данных CRM (а не скопированных экспортов).

  • Инженеры, подключающие MCP к внутренним инструментам: транспорт stdio, типизированные входные данные Zod и отсутствие поверхности записи — безопасно экспериментировать с промптами и агентами.

  • Команды данных и операций, запускающие дашборды: используйте qobrix_count / qobrix_top_values для метрик типа «год к году» без пользовательских скриптов и кэширование ответов для снижения нагрузки на API при повторяющихся запросах.

  • Корпоративный ИТ-отдел, готовый к идентификации на уровне агента: запускайте режимы A/B из этого пакета, затем сочетайте режим C с продуктом Enterprise OAuth (SSO) от SharpSir, когда каждый пользователь должен аутентифицироваться как отдельная личность — см. Корпоративный OAuth.

Канонические рабочие процессы в сфере недвижимости

Сервер организован вокруг шести бизнес-процессов, согласованных с RESO. LLM получает их как встроенные инструкции, чтобы ориентироваться в CRM без предварительного обучения.

#

Рабочий процесс

Сопоставление с RESO

Ключевые инструменты

1

Жизненный цикл объявления

Property.StandardStatus

search_properties, get_property, list_media, get_property_coordinates

2

Жизненный цикл лида и контакта

Воронка Contacts.ContactType

search_opportunities, get_contact, search_tasks

3

Воронка продаж

8-этапный путь покупателя

get_leads_by_property, get_lead_properties, list_viewings, list_offers, list_contracts

4

Показ / просмотр

ShowingAppointment

list_viewings, get_viewing, list_meetings

5

Сделка / предложение

TransactionManagement

list_offers, get_offer, list_contracts, get_contract

6

Активность / последующие действия

Отслеживание вовлечённости

list_calls, list_meetings, list_email_messages, search_tasks

Сопоставление статусов

Статус объекта Qobrix

RESO StandardStatus

available

Active

reserved

Pending / Under Contract

sold

Closed

withdrawn

Withdrawn / Canceled

Статус возможности Qobrix

Воронка лидов RESO

new

MQL / Raw Lead

open

SQL / Active

won

Closed Won

closed_lost

Lost


Инструменты кратко

64 инструмента — сущности CRM, обнаружение схем, аналитика (qobrix_count, qobrix_top_values, qobrix_top_records, qobrix_aggregate), гибкий ярлык сделок (qobrix_deals), отчётность (qobrix_timeseries, qobrix_funnel, qobrix_rep_scorecard, qobrix_stale_leads, qobrix_win_loss, qobrix_days_on_market), аналитика по клиентам (qobrix_cohort), аудит / история изменений (qobrix_get_changes, qobrix_search_changes, qobrix_field_change_history, qobrix_top_field_changers), вспомогательные инструменты кэша (qobrix_cache_stats, qobrix_cache_clear) и сессии и идентификация (qobrix_sign_in, qobrix_sign_out, qobrix_whoami):

Группа сущностей

Инструменты

Возможности

Объекты

5

List, Get, Search, Coordinates (карта), Properties-by-Lead

Контакты

3

List, Get, Search

Агенты

3

List, Get, Search

Возможности / Лиды

5

List, Get, Search, Leads-by-Property, Lead-Properties

Показы объектов

3

List, Get, Search

Задачи

3

List, Get, Search

Медиа

2

List (с фильтром по сущности), Get (с вариантами размеров)

Проекты

4

List, Get, Search, Coordinates

Предложения

3

List, Get, Search

Договоры

3

List, Get, Search

Звонки

2

List, Get

Встречи

2

List, Get

Электронные письма

2

List, Get

Схема / метаданные

3

Get Schema (обнаружение полей), Get Field Options (значения перечислений), Search DSL Help (полная грамматика + шпаргалки)

Аналитика

4

Подсчеты, топ-N значений полей, топ-N записей при полном сканировании по числовому полю/дате, агрегаты sum/avg/min/max/count (с группировкой по одному или нескольким измерениям). Для одной страницы предпочитайте sort в list/search; используйте top_records/aggregate для полного сканирования набора или для nullable-полей

Сделки

1

Гибкий доменный ярлык над таблицей Contracts (продажи, аренда, листинги, воронка) с параметрами kind / contract_types[] / contract_statuses[] / date_field / min_price / party filters / summary block

Отчетность

6

Временные ряды с YoY (qobrix_timeseries), каноническая воронка продаж + процент конверсии (qobrix_funnel), табель показателей по сотрудникам / лидерборд агентов (qobrix_rep_scorecard), обнаружение «молчащих» лидов (qobrix_stale_leads), аналитика выигрышей (qobrix_win_loss), срок на рынке (qobrix_days_on_market)

Клиенты

1

Когорты повторных покупателей / продавцов / лидов (qobrix_cohort) — находит контакты, которые фигурируют в нескольких закрытых сделках или возможностях

Аудит

4

Журнал изменений по записи (qobrix_get_changes), межресурсный поиск изменений (qobrix_search_changes), история изменений на уровне полей (qobrix_field_change_history), топ изменяющих поля (qobrix_top_field_changers)

Кэш

2

Статистика и инвалидация по префиксу или полная инвалидация для получения более свежих данных

Сессия и идентификация

3

Интерактивный вход (qobrix_sign_in), выход с полным отзывом токенов (qobrix_sign_out), профиль текущего пользователя (qobrix_whoami) — режим C; разумные no-op в режимах A/B

Описание каждого инструмента включает его каноническую роль в рабочем процессе, аналог RESO, проверенные опции include[], рекомендации по разрешению внешних ключей (FK) и примеры поисковых выражений.

Примеры использования аналитики и сделок

Серверный sort (в OpenAPI — sort[]) работает для большинства полей, например sort: "-list_selling_price_amount" для объектов. Используйте qobrix_top_records / qobrix_aggregate, когда требуется полное сканирование набора данных или когда nullable-поле (например, opportunities.budget) не возвращает строк при серверной сортировке. «Закрытые сделки» не хранятся в виде флага объекта недвижимости — это строки в таблице Contracts. Инструменты аналитики и сделок устраняют необходимость в клиентских скриптах:

// 1) Top 5 closed 2026 sales, sorted by final_selling_price_amount,
//    with property + agent + lawyers resolved to readable names.
{
  "tool": "qobrix_top_records",
  "args": {
    "resource": "contracts",
    "sort_by": "final_selling_price_amount",
    "search": "contract_type == \"cos\" and contract_status == \"agreed\" and date_of_contract >= \"2026-01-01\" and date_of_contract < \"2027-01-01\"",
    "top": 5
  }
}

// 2) 2026 sales volume, plus an agent leaderboard in one extra call.
{
  "tool": "qobrix_aggregate",
  "args": {
    "resource": "contracts",
    "field": "final_selling_price_amount",
    "op": "sum",
    "search": "contract_type == \"cos\" and contract_status == \"agreed\" and date_of_contract >= \"2026-01-01\" and date_of_contract < \"2027-01-01\"",
    "group_by": "commission_to_2",
    "top": 10
  }
}

// 3) Flexible "deals" shortcut — same answer as (1) with one default-laden call,
//    plus a full-set summary block (by_status, by_type, totals, median).
{ "tool": "qobrix_deals", "args": { "year": 2026, "top": 5 } }

// 4) Best 2026 rental contracts by final rental price.
{ "tool": "qobrix_deals", "args": { "kind": "rental", "year": 2026, "top": 5 } }

// 5) Under-contract reservations + closed sales together (pipeline + actuals).
{
  "tool": "qobrix_deals",
  "args": { "contract_statuses": ["reserved", "agreed"], "year": 2026 }
}

// 6) "My deals this year": uses the CURRENT_USER special var.
{
  "tool": "qobrix_deals",
  "args": { "assigned_to": "CURRENT_USER", "year": 2026 }
}

// 7) Monthly 2026 closed-sale volume with prior-year YoY %.
{
  "tool": "qobrix_timeseries",
  "args": {
    "resource": "contracts",
    "bucket": "month",
    "metric": "sum",
    "field": "final_selling_price_amount",
    "year": 2026,
    "search": "contract_type == \"cos\" and contract_status == \"agreed\"",
    "compare_to_prior": true
  }
}

// 8) Full 2026 sales funnel (Leads → Qualified → Viewing → Offer → Reserved → Closed).
{ "tool": "qobrix_funnel", "args": { "year": 2026 } }

// 9) 2026 agent leaderboard by volume (omit `user` for leaderboard mode).
{ "tool": "qobrix_rep_scorecard", "args": { "year": 2026, "sort_by": "volume", "top": 10 } }

// 10) Silent leads — open opportunities with no activity in 30 days.
{ "tool": "qobrix_stale_leads", "args": { "since_days": 30 } }

// 11) Multi-dim pivot: 2026 closed-sale volume by city × property_type.
{
  "tool": "qobrix_aggregate",
  "args": {
    "resource": "contracts",
    "field": "final_selling_price_amount",
    "op": "sum",
    "search": "contract_type == \"cos\" and contract_status == \"agreed\" and date_of_contract >= \"2026-01-01\" and date_of_contract < \"2027-01-01\"",
    "group_by": ["property_id", "contract_type"],
    "top": 10
  }
}

// 12) Repeat buyers — contacts behind 2+ closed sales in 2026.
{ "tool": "qobrix_cohort", "args": { "kind": "buyers", "year": 2026, "min_count": 2 } }

// 13) Win-rate by lead source in 2026, with top loss reasons resolved.
{
  "tool": "qobrix_win_loss",
  "args": { "year": 2026, "group_by": "source", "include_top_losses": true }
}

// 14) 2026 days-on-market by property type, with longest/shortest outliers.
{
  "tool": "qobrix_days_on_market",
  "args": { "kind": "sold", "year": 2026, "group_by": "property_type", "include_outliers": true }
}

Быстрый старт

git clone https://github.com/gca-ltd/qobrix-crm-mcp.git
cd qobrix-crm-mcp
npm install
npm run build

Конфигурация

Создайте файл .env в корне проекта:

QOBRIX_API_URL=https://yourcrm.qobrix.com
QOBRIX_API_USER=your-api-user-uuid
QOBRIX_API_KEY=your-api-key
QOBRIX_LOCALE=en-US          # optional

Переменная

Обязательная

Описание

QOBRIX_API_URL

Да (режим A)

Базовый URL экземпляра Qobrix

QOBRIX_API_USER

Да (режим A)

Значение заголовка X-Api-User (UUID)

QOBRIX_API_KEY

Да (режим A)

Значение заголовка X-Api-Key

QOBRIX_LOCALE

Нет

Заголовок X-Locale (например, en-US, el-GR)

Режимы аутентификации

Клонируйте этот пакет, запустите режим A или B и подключите живые данные Qobrix к Claude, Cursor или любому MCP-клиенту — Apache 2.0.

Режим

В этом пакете?

Когда

Как передаются учетные данные

A (по умолчанию)

Да

QOBRIX_MCP_TRANSPORT=stdio (или не задан)

Общие QOBRIX_API_* из переменных окружения процесса

B

Да

TRANSPORT=http + QOBRIX_MCP_AUTH=headers

В каждом запросе — X-Api-User / X-Api-Key (доверенные вызывающие; привязка к localhost)

C

Требуется внешний AS

TRANSPORT=http + QOBRIX_MCP_AUTH=oauth

Самообслуживание OAuth: MCP возвращает URL /connect; пользователь входит в Authorization Server SharpSir Enterprise OAuth; этот сервер хранит сессию

D (по желанию)

Требуется внешний AS

TRANSPORT=http + QOBRIX_MCP_AUTH=oauth-claude

Удаленный MCP OAuth (RFC 9728 PRM + Bearer на /mcp) для Claude.ai / Desktop custom connectors и Dust.tt Spaces tools — тот же URL ресурса, вход для каждого пользователя

Режимы A и B полностью поддерживаются этим пакетом. Режимы C и D требуют отдельного продукта SharpSir Enterprise OAuth / SSO — он не распространяется в составе этого репозитория. Режим D не изменяет режимы A/B/C — выбирайте его, когда нужно, чтобы удаленные хосты, такие как Claude.ai или Dust.tt, сами выполняли OAuth.

Enterprise OAuth

Нужно, чтобы агент работал как вошедший пользователь Qobrix, а не через общий API-ключ? Для этого предназначен режим C. Он требует решения Enterprise OAuth от SharpSir: размещенного комплекта Authorization Server (вход + 2FA + согласие, выпуск API-ключей для каждого пользователя, зашифрованное хранилище учетных данных, токены, привязанные к аудитории), который работает исключительно с этим MCP-сервером.

Как работает режим C (самостоятельная аутентификация MCP — вышестоящие клиенты не меняются):

  1. Инструмент запускается без сессии → MCP возвращает URL авторизации:

    • Выявление через URL (JSON-RPC -32042), когда клиент поддерживает elicitation.url (Claude, Cursor и т.д.)

    • Markdown-ссылка [Sign In to Qobrix](/connect?e=…) в результате работы инструмента для клиентов без выявления (например, ragchat / LangChain) — LLM должен передать её дословно (уникальная / одноразовая; никогда не переиспользуйте старую ссылку)

  2. Пользователь открывает /connect на этом сервере (перенаправление против фишинга) → подписанный cookie + редирект на страницу входа Enterprise OAuth

  3. После входа + 2FA + согласия AS перенаправляет на /oauth/callback; этот MCP обменивает код (PKCE), проверяет учётные данные Qobrix и сохраняет их в зашифрованном хранилище сессий

  4. Следующий вызов инструмента выполняется аутентифицированным. При Qobrix 401/403 хранилище очищается и возвращается новый URL /connect

  5. Агенты также могут вызывать qobrix_sign_in, qobrix_whoami и qobrix_sign_out (полный отзыв через AS /disconnect + удаление API-ключа Qobrix)

  • Недоступен как публичная загрузка и не может быть склонирован с GitHub.

  • Поставляется и настраивается нашей командой по запросу как корпоративный пакет решений.

  • Никаких сторонних OAuth-серверов — Mode C жёстко привязан только к этому корпоративному OAuth-решению.

  • Безопасность: Mode C использует зашифрованные хранилища сессий для каждого пользователя (привязанные к заголовкам идентичности чата) и оставляет /mcp без клиентского bearer. Привяжите QOBRIX_MCP_HOST=127.0.0.1 и задайте QOBRIX_MCP_IDENTITY_SECRET (передаётся только доверенному MCP-хосту, например ragchat), чтобы заголовки идентичности нельзя было подделать. Держите шифрование хранилища на QOBRIX_MCP_STATE_SECRET (только для MCP). Если вы используете обратный прокси для браузеров, публикуйте только /connect и /oauth/callback — запретите публичный доступ к /mcp и /health. Локальные агенты (ragchat) вызывают http://127.0.0.1:<port>/mcp. Когда в ALLOWED_HOSTS указан только публичный hostname, значения loopback Host (127.0.0.1 / localhost / ::1) добавляются автоматически, если сервер привязан к loopback. Cookie подключения Path следует за pathname из PUBLIC_URL; Express trust proxy равен 2 за Cloudflare→Apache. Передавайте ссылки /connect только конкретному пользователю — никогда в общий/групповой чат.

Готовы к обновлению? Свяжитесь с SharpSir Group · dev@sharpsir.group и запросите пакет Qobrix CRM MCP Enterprise OAuth.

После поставки вы указываете этому серверу на issuer, который получите:

export QOBRIX_MCP_TRANSPORT=http
export QOBRIX_MCP_AUTH=oauth
export QOBRIX_MCP_HOST=127.0.0.1
export QOBRIX_MCP_PORT=3502
export QOBRIX_MCP_PUBLIC_URL=http://127.0.0.1:3502
export QOBRIX_MCP_RESOURCE_URL=http://127.0.0.1:3502/mcp
export QOBRIX_OAUTH_ISSUER=<issuer-from-enterprise-bundle>
export QOBRIX_OAUTH_INTROSPECTION_SECRET=<shared-secret-from-bundle>
export QOBRIX_MCP_STATE_SECRET=<16+-char-secret>
export QOBRIX_MCP_IDENTITY_SECRET=<16+-char-secret-shared-with-ragchat>
export QOBRIX_MCP_DATA_DIR=./data/mcp-oauth
export QOBRIX_MCP_ALLOWED_HOSTS=qobrix-mcp.example.com   # loopback Hosts auto-added when HOST is 127.0.0.1
npm start

Endpoint'ы Mode C (после подключения корпоративного OAuth-решения):

  • GET /connect?e=… — начало авторизации (устанавливает cookie, 302 на AS)

  • GET /oauth/callback — обмен кода PKCE + запись в хранилище сессий для пользователя

  • GET /health — включает connected и количество session_vaults

  • Неаутентифицированный /mcp намеренно для северных клиентов: инструменты показывают URL подключения при необходимости — держите /mcp на localhost в продакшене

См. docs/USER_GUIDE.md для пошагового перехода Mode A → B → C, ограничения обратного прокси и деталей allowlist Host.

Для ragchat / Mode C зарегистрируйте удалённый MCP URL (…/mcp) как обычный Streamable HTTP-сервер (клиентский OAuth-провайдер не требуется); MCP обрабатывает аутентификацию через /connect. Держите /mcp на localhost в этой топологии.

Mode D — удалённый MCP Claude.ai и Dust.tt (общий ресурс)

Используйте отдельный MCP-процесс (или хост) с QOBRIX_MCP_AUTH=oauth-claude. Удалённые хосты сами выполняют OAuth против того же HTTPS /mcp URL:

Хост

Как подключиться

Аутентификация

Claude.ai / Claude Desktop

Settings → Connectors → Add custom connector

Автоматический DCR + PKCE (редирект https://claude.ai/api/mcp/auth_callback)

Dust.tt

Spaces → Tools → Add MCP Server

Предпочтительно Automatic; запасной вариант Static OAuth — см. INSTALL — Connect Dust

  1. Пользователь вставляет https://intranet.sharpsir.group/qobrix-crm/mcp в Claude или Dust

  2. Хост обращается к /mcp → получает 401 + WWW-Authenticate: Bearer resource_metadata=…

  3. Хост получает /.well-known/oauth-protected-resource → обнаруживает QOBRIX_OAUTH_ISSUER

  4. Хост завершает OAuth (DCR или Static) + PKCE против корпоративного OAuth AS

  5. Последующие вызовы /mcp отправляют Authorization: Bearer <access_token>; этот сервер выполняет introspection и запускает инструменты от имени этого пользователя Qobrix

Claude и Dust используют один стек Mode D (тот же MCP-ресурс + тот же Authorization Server). Каждый хост регистрирует свой OAuth-клиент; каждый участник входит в Qobrix как сам.

export QOBRIX_MCP_TRANSPORT=http
export QOBRIX_MCP_AUTH=oauth-claude
export QOBRIX_MCP_HOST=127.0.0.1
export QOBRIX_MCP_PORT=3502
export QOBRIX_MCP_ALLOWED_HOSTS=intranet.sharpsir.group
export QOBRIX_MCP_PUBLIC_URL=https://intranet.sharpsir.group/qobrix-crm
export QOBRIX_MCP_RESOURCE_URL=https://intranet.sharpsir.group/qobrix-crm/mcp
export QOBRIX_OAUTH_ISSUER=https://intranet.sharpsir.group/qobrix-crm/mcp-oauth
export QOBRIX_OAUTH_INTROSPECTION_SECRET=<shared-secret-from-bundle>
npm start

На AS, при использовании allowlist редиректов, сохраните callback Claude и добавьте точные финальные URL Dust (никогда не заменяйте запись Claude):

export QOBRIX_OAUTH_REDIRECT_ALLOWLIST=https://claude.ai/api/mcp/auth_callback,http://127.0.0.1,http://localhost,cursor://,https://eu.dust.tt/oauth/mcp/finalize,https://eu.dust.tt/oauth/mcp_static/finalize,https://dust.tt/oauth/mcp/finalize,https://dust.tt/oauth/mcp_static/finalize,https://app.dust.tt/oauth/mcp/finalize,https://app.dust.tt/oauth/mcp_static/finalize

Публикуйте HTTPS /mcp + PRM (и AS) в публичный интернет; разрешите исходящий трафик Anthropic 160.79.104.0/21 при WAF, и дополнительно разрешите исходящий трафик Dust — не удаляйте allowlist Claude. Рекомендации Mode C по loopback/deny public /mcp остаются в силе для развёртываний ragchat — не меняйте эту топологию для процессов Mode C.

Полные шаги: INSTALL — Connect Claude · INSTALL — Connect Dust · Dust: Adding an MCP Server.

Кэширование

Все инструменты MCP — это read-only GET-запросы, поэтому кэш ответов не может повредить состояние CRM. Сервер оборачивает одну точку входа (QobrixClient.request()) сквозным кэшем, поэтому каждый вызов list/get/search/schema — включая каждую страницу релевантного max_scan — кэшируется. Оценка boost выполняется после получения данных и не меняет ключ кэша, поэтому повторное ранжирование с разными boost[] переиспользует те же страницы-кандидаты.

Дизайн — cache-aside с single-flight коалесценцией:

  • Уровень 1 — in-memory LRU (всегда включён, без зависимостей): на процесс, с TTL, с ограничением размера.

  • Уровень 2 — Redis (опционально, лениво загружается через динамический import()): задайте QOBRIX_REDIS_URL для включения; сервер откатывается к памяти только при любой ошибке Redis.

  • Single-flight: когда LLM запускает параллельные вызовы инструментов, попадающие в один холодный ключ кэша (часто с qobrix_top_values), все вызывающие в одном процессе делят один upstream-запрос.

  • Ошибки никогда не кэшируются — временный 5xx не застрянет.

  • Только TTL, без stale-while-revalidate в v1.

Переменные окружения:

Переменная

По умолчанию

Описание

QOBRIX_CACHE_ENABLED

true

Установите false для полного обхода кэша

QOBRIX_CACHE_TTL

300

TTL в секундах; изменения CRM видны в этом окне

QOBRIX_CACHE_MAX_ENTRIES

5000

LRU-предел для in-memory уровня

QOBRIX_REDIS_URL

(пусто)

URL redis:// / rediss://; пусто = только память

QOBRIX_REDIS_KEY_PREFIX

qobrix:

Пространство имён при совместном использовании экземпляра Redis

Инструменты кэша (доступны LLM):

Инструмент

Использование

qobrix_cache_stats

Хиты/промахи/размер/в полёте/статус Redis — проверьте, что кэш окупается

qobrix_cache_clear

Инвалидация всех ключей или по prefix (например, v1:request:opportunities) для мгновенного обновления до истечения TTL

Рекомендуемая конфигурация Redis-сервера (для выделенного кэш-только Redis, согласно документации Redis):

maxmemory 256mb
maxmemory-policy allkeys-lru
maxmemory-samples 10

Рекомендации по TTL — документация Redis рекомендует короткие TTL для часто меняющихся данных (60–120 с) и более длинные для стабильных (часы). 300 с — консервативное значение по умолчанию для CRM, которая смешивает воронку лидов (меняется ежеминутно) с листингами недвижимости (меняются ежечасно). Используйте qobrix_cache_clear, когда нужен мгновенный обновление.

Компромисс / известное ограничение: Коалесценция single-flight работает только в рамках процесса. Мультиинстансные развёртывания за одним общим Redis могут всё ещё видеть умеренный stampede на холодных ключах; распределённая блокировка SETNX — будущая работа и не требуется для однопользовательских MCP-клиентов.

Соответствие лучшим практикам:

Лучшая практика

Где соблюдается

Cache-aside / read-through (документация Redis, руководства по кэшированию MCP)

Обёртка QobrixClient.request()

Канонический, версионированный ключ кэша

cacheKey("v1", ...) с отсортированными параметрами

Консервативный TTL

300s по умолчанию, переопределяется через env

Ошибки не кэшируются

Обёртка сохраняет только при успешном upstream-ответе

Предотвращение stampede через single-flight

In-process карта inflight

allkeys-lru для кэш-только Redis

Документировано выше для self-hosters

Наблюдаемость + ручная инвалидация

qobrix_cache_stats, qobrix_cache_clear

Официальный Node.js Redis-клиент

redis (node-redis), как optionalDependencies

Настройка Cursor IDE

Этот сервер использует stdio MCP (локальный процесс node). Cursor обнаруживает серверы из project или user mcp.json: .cursor/mcp.json внутри открытой папки или ~/.cursor/mcp.json для всех рабочих пространств.

1. Предварительные требования

  • Node.js 20+ на машине, где Cursor запускает MCP (локальный ноутбук или удалённый SSH-хост).

  • Клонируйте этот репозиторий, установите и соберите (см. Quick Start).

  • dist/index.js должен существовать (npm run build) перед добавлением записи MCP.

2. Учётные данные

  1. Скопируйте шаблон: cp .env.example .env

  2. Отредактируйте .env и задайте как минимум QOBRIX_API_URL, QOBRIX_API_USER и QOBRIX_API_KEY (см. Configuration).

  3. Держите .env вне git; он указан в .gitignore.

3. Куда поместить JSON

Расположение

Когда использовать

<project>/.cursor/mcp.json

Вы открыли эту папку проекта в Cursor; коллеги могут закоммитить шаблон (без секретов) или вы держите его только локально.

~/.cursor/mcp.json

Тот же MCP в каждом рабочем пространстве на этой машине.

Объедините свою запись в существующий объект "mcpServers"; не заменяйте весь файл, если у вас уже есть другие серверы.

4. Рекомендуется: node --env-file (Node 20+)

Передавайте абсолютные пути, чтобы это работало одинаково, независимо от того, является ли корень рабочего пространства этим репозиторием или родительской папкой (и чтобы удалённые SSH-пути разрешались корректно).

{
  "mcpServers": {
    "qobrix-crm-mcp": {
      "command": "node",
      "args": [
        "--env-file=/absolute/path/to/qobrix-crm-mcp/.env",
        "/absolute/path/to/qobrix-crm-mcp/dist/index.js"
      ],
      "description": "Read-only Qobrix CRM MCP"
    }
  }
}

Почему этот паттерн:

  • Учётные данные остаются в .env, а не в JSON.

  • Node загружает файл до запуска вашего сервера, поэтому process.env заполнен, даже если поле envFile хоста игнорируется или ведёт себя непоследовательно для stdio-серверов.

5. Альтернатива: встроенный env

Полезно, если вы не можете использовать --env-file (старый Node). Секреты живут в mcp.json — ограничьте права на файл и не коммитьте их.

{
  "mcpServers": {
    "qobrix-crm-mcp": {
      "command": "node",
      "args": ["/absolute/path/to/qobrix-crm-mcp/dist/index.js"],
      "env": {
        "QOBRIX_API_URL": "https://yourcrm.qobrix.com",
        "QOBRIX_API_USER": "your-api-user-uuid",
        "QOBRIX_API_KEY": "your-api-key",
        "QOBRIX_LOCALE": "en-US"
      }
    }
  }
}

Вы также можете использовать интерполяцию конфигурации Cursor (например, ${env:QOBRIX_API_KEY}), чтобы значения подставлялись из переменных окружения вашей ОС, а не литералов.

6. Необязательно: envFile в MCP JSON

Cursor поддерживает свойство envFile для stdio-серверов. В некоторых конфигурациях эти переменные не передаются дочернему процессу надёжно; если инструменты завершаются с ошибкой «Missing required environment variables», переключитесь на --env-file, как в шаге 4.

7. После редактирования mcp.json или .env

  1. Перезагрузите MCP — Command Palette → перезапуск MCP или перезагрузка окна Cursor.

  2. Проверьте логи — View → Output → выберите «MCP» / «MCP Logs» в выпадающем списке; исправьте ошибки путей или Node там.

  3. Подтверждение инструментов — по умолчанию Cursor запрашивает подтверждение перед каждым вызовом инструмента; при желании вы можете разрешить автозапуск для доверенных инструментов в настройках Cursor.

Другие MCP-хосты

Claude.ai / Claude Desktop (Режим D) — удалённый пользовательский коннектор по адресу https://intranet.sharpsir.group/qobrix-crm/mcp. См. Режим D и INSTALL — Подключение Claude.

Dust.tt (Режим D) — Spaces → Tools → Add MCP Server с тем же URL. Предпочитайте Automatic auth и Personal accounts. См. INSTALL — Подключение Dust.

Claude Desktop / Cursor (Режим A stdio) — та же stdio-форма: command + args для node и либо --env-file, либо env в MCP-конфиге хоста.

CI / headless — запустите node --env-file=.env dist/index.js с stdio-клиентской библиотекой MCP; убедитесь, что .env передаётся через секреты, а не коммитится.


Синтаксис поисковых выражений

Инструменты, принимающие параметр search, используют Symfony Expression Language от Qobrix (OpenAPI SearchExpression). Вызовите qobrix_search_dsl_help для получения полной грамматики + шпаргалок по полям объектов/проектов (опционально с именами полей из живой схемы).

Возможность

Синтаксис

Пример

Равенство

==, !=, <>

status == "available"

Сравнение

<, >, <=, >=

list_selling_price_amount <= 500000

Содержит

contains, starts with, ends with

city contains "Limas"

Принадлежность

in [...], not in [...]

property_type in ["villa","house"]

Диапазон

in min..max

bedrooms in 2..4

Логические

and, or, not, скобки

status == "available" and sale_rent == "for_sale"

Помощники по датам

DAYS_AGO(n), MONTHS_AGO(n), DAYS_FROM_NOW(n), …

created >= DAYS_AGO(30)

Сокращения времени

NOW, TODAY, THIS_WEEK, LAST_MONTH, THIS_YEAR, …

created >= LAST_MONTH

Текущий пользователь

CURRENT_USER

assigned_to == CURRENT_USER

Гео / прочее

DISTANCE_FROM, IN_POLYGON, TRANSLATED, MIN/MAX

DISTANCE_FROM(coordinates, "34.43,32.13") <= 5000

Путь ассоциации

Entity.field

SalespersonUsers.Contacts.country == "CY"

Совет: вызовите qobrix_search_dsl_help({ resource: "Properties" }) перед тем, как преобразовывать свободно сформулированный запрос в поисковый. Используйте qobrix_get_field_options для значений перечислений и qobrix_get_schema для полного списка полей.

Релевантный поиск по всем ресурсам (F1)

Каждый инструмент qobrix_search_* (объекты, проекты, контакты, агенты, сделки, показы, задачи, предложения, договоры) использует двухуровневую архитектуру, чтобы свободно сформулированный запрос обеспечивал и высокую точность, и высокую полноту:

  1. search — жёсткие обязательные условия (серверный DSL-фильтр → нижняя граница точности).

  2. boost[] — мягкие взвешенные желательные условия, оцениваемые в процессе над пулом кандидатов (полнота + ранжирование).

  3. limit — сколько ранжированных строк вернуть (по умолчанию 10, максимум 100). Увеличивайте для большего выбора; держите умеренным, чтобы не перегружать контекст.

  4. max_scan — пул кандидатов при бустинге (по умолчанию 100, жёсткий предел 500). Больше — выше полнота; каждая просканированная страница кэшируется в ответе.

С boost каждая строка включает _relevance (оценку) и _matched (какие условия сработали); pagination.mode равен "ranked". Без boost возвращается одна закэшированная страница списка (mode: "fast").

qobrix_search_properties({
  search: 'status == "available" and sale_rent == "for_sale"',
  boost: [
    { field: "sea_view", op: "==", value: true, weight: 3 },
    { field: "bedrooms", op: ">=", value: 3, weight: 2 },
    { field: "list_selling_price_amount", op: "in", value: "200000..600000", weight: 2 },
  ],
  limit: 15,
  max_scan: 200,
});

Сопоставление лида ↔ объекта через поиск (в обе стороны)

  • Спрос → предложение: возьмите критерии лида → qobrix_search_properties / qobrix_search_projects с search+boost. Нативно: qobrix_get_properties_by_lead / qobrix_get_lead_properties.

  • Предложение → спрос: qobrix_search_opportunities с search + boost по открытому лиду против объекта (работает и для проектов). Нативно только для объектов: qobrix_get_leads_by_property.

// Who wants a Limassol 3-bed ~€400k listing?
qobrix_search_opportunities({
  search: 'status in ["new","open"] and buy_rent == "buy"',
  boost: [
    { field: "area_of_interest", op: "contains", value: "Limassol", weight: 3 },
    { field: "bedrooms_from", op: "<=", value: 3, weight: 2 },
    { field: "list_selling_price_to", op: ">=", value: 400000, weight: 2 },
  ],
  limit: 15,
  max_scan: 200,
});

Операторы бустинга: == != < > <= >= in contains starts_with ends_with. Для диапазонов используйте op: "in" со значением value: "min..max".

Поиск (и все остальные list/get) использует общий TTL кэша (QOBRIX_CACHE_TTL, по умолчанию 300 с). После изменений в CRM обновите кэш через qobrix_cache_clear({ prefix: "v1:request:properties" }) (или opportunities, projects, …).


Получение связанных данных

Три стратегии разрешения внешних ключей:

  1. Параметр include[] — развернуть ассоциации инлайн за один вызов

qobrix_get_property({ id: "...", include: ["Agents", "PropertyViewings"] })
  1. Отдельный get-вызов — взять UUID из поля внешнего ключа и вызвать соответствующий инструмент

// property.agent → UUID
qobrix_get_agent({ id: "<agent-uuid>" })
  1. Поиск по внешнему ключу — найти связанные записи через поисковое выражение

qobrix_search_properties({ search: 'agent == "<agent-uuid>"' })

Только значения include[], помеченные как Verified в описаниях инструментов, гарантированно работают. Если include[] недоступен для ассоциации, используйте поиск по внешнему ключу.


Значения по умолчанию для полезной нагрузки

Чтобы результаты инструментов оставались достаточно короткими для контекстного окна вызывающей LLM, list / search / get инструменты по умолчанию возвращают компактные полезные нагрузки:

Параметр

По умолчанию

Эффект при значении по умолчанию

expand

false

Внешние ключи возвращаются как UUID-строки вместо разворачивания во вложенные объекты. Разрешайте их по требованию соответствующим get-инструментом или точечным include[].

media

false

Встроенные медиа (фото, планы этажей, URL миниатюр) не прикрепляются к строкам списка. Используйте qobrix_list_media({ related_model: 'Properties', related_id: '<uuid>' }), когда медиа действительно нужны.

Переопределяйте на один вызов только тогда, когда вызывающей стороне действительно нужна более тяжёлая полезная нагрузка:

// Cheap browse — recommended for most reporting / pipeline calls
qobrix_list_properties({ limit: 10 });

// Heavy detail — only when the LLM truly needs nested FKs + media URLs
qobrix_list_properties({ limit: 5, expand: true, media: true });

// Prefer surgical include[] over full expand=true:
qobrix_get_property({ id: "...", include: ["AgentAgents", "ProjectProjects"] });

Это изменение обычно сокращает qobrix_list_properties({ limit: 10 }) с ~300 КБ до ~5–10 КБ.


Ограничение вывода

Каждый результат инструмента ограничен QOBRIX_MCP_MAX_RESULT_CHARS символами отрисованного JSON (по умолчанию 30 000, примерно 7,5 тыс. токенов). Поведение:

  • Пагинированные полезные нагрузки ({ data: [...], pagination: {...} }): усекаются до наибольшего префикса data[], который помещается, и добавляется блок _truncated с kept_rows, omitted_rows, original_chars, max_chars и hint, подсказывающим LLM, как сузить следующий вызов. Если одни вложенные expand/media объекты превышают лимит, строки сжимаются до скаляров (_truncated.compacted: true), чтобы вернулась хотя бы одна пригодная строка.

  • Сильно превышающие размер (по умолчанию: исходный размер > 8 × лимита, переопределение QOBRIX_MCP_REFINE_MULTIPLIER): возвращается status: "result_too_large" с _refine_required (инструкция ассистенту + предложение по сужению + небольшой returned_sample), чтобы LLM попросила пользователя переформулировать запрос, а не вываливала данные.

  • Непагинированные полезные нагрузки (одиночный get, пользовательские аналитические формы): JSON обрезается до лимита, и добавляется хвост QOBRIX_MCP TRUNCATED (или та же директива refine при сильном превышении).

Когда boost используется с expand=true или media=true, max_scan автоматически ограничивается 100, и pagination.scan_capped_reason может быть "expand/media".

Переопределение лимита / порога refine:

QOBRIX_MCP_MAX_RESULT_CHARS=60000
QOBRIX_MCP_REFINE_MULTIPLIER=8

Если вы регулярно упираетесь в лимит или защиту refine, используйте fields[] (белый список колонок), более точное выражение search, меньший limit или оставляйте expand=false / media=false.


Тестирование

Проект включает 226 автоматических тестов в 63 наборах describe (интеграция, многошаговые сценарии, RESO-процессы, кэш, релевантность, ограничение вывода, клиентская сортировка и смоук-тесты OAuth-режима):

# Integration tests — individual tool mechanics
npm test

# Scenario tests — multi-step tool chains (19 real-world scenarios)
npm run test:scenarios

# Workflow tests — canonical RE business processes (8 RESO-aligned suites)
npm run test:workflows

# Cache tests — read-through, single-flight, LRU eviction, search-page keys (no API needed)
npm run test:cache

# Relevance tests — boost scoring, DSL help, search cache keys (no API needed)
npm run test:relevance

# Format tests — output cap + truncation behaviour (no API needed)
npm run test:format

# OAuth modes smoke — Mode B header rejection + Mode C /connect elicitation path
npm run test:oauth-modes

# Run everything
npm run test:all

Набор

Тесты

Покрытие

Интеграция

70

Каждый инструмент, граничные случаи пагинации, механика include/fields, аналитические и отчётные инструменты

Сценарии

55

Утренний брифинг агента, поиск покупателя, триаж лидов, цепочки внешних ключей, отчёты по воронке

Процессы

39

Жизненный цикл объекта, воронка лидов, воронка продаж, показ, сделка, медиа, активность, схема

Кэш

22

Сквозной кэш, объединение single-flight, LRU-вытеснение, канонизация ключей, ключи страниц поиска (без живого API)

Релевантность

23

Оценка/скоринг/ранжирование boost (включая формы сделок/контактов), объединение fields[]+boost, текст справки DSL, стабильность ключей поискового кэша (без живого API)

Формат

7

Ограничение вывода formatResult, усечение пагинации, сжатие expand/media (kept_rows>=1), защита refine result_too_large, запасной хвост, переопределение env (без живого API)

Клиентская сортировка

7

normalizeSort + buildQobrixUrl генерируют OpenAPI sort[]= (а не скалярный sort=, который Qobrix игнорирует)

OAuth-режимы

4

Заголовки режима B, /connect режима C, PRM/401/Bearer режима D


Архитектура

src/
├── index.ts          # MCP server entry point + RESO workflow instructions
├── http.ts           # Streamable HTTP transport (Modes B / C)
├── modes.ts          # Auth mode resolution (env / headers / oauth / oauth-claude)
├── client.ts         # QobrixClient — HTTP + read-through response cache
├── auth-context.ts   # AsyncLocalStorage per-request credentials
├── oauth-client.ts   # Mode C self-service OAuth client + session vault
├── oauth-rs.ts       # Companion AS metadata + introspection helpers
├── request-context.ts# ALS for McpServer (elicitation capability detection)
├── cache.ts          # LRU memory tier, optional Redis, single-flight coalescing
├── relevance.ts      # Boost scoring + cached candidate pager for search
├── search-dsl.ts     # Full SearchExpression DSL reference + field cheatsheets
├── types.ts          # TypeScript interfaces
├── schemas.ts        # Zod schemas with rich LLM-facing descriptions
└── tools/
    ├── index.ts      # Tool registration hub + formatResult / errorResult
    ├── properties.ts # Listing Lifecycle + relevance search
    ├── contacts.ts   # Lead-Contact Lifecycle tools
    ├── agents.ts     # RESO Member tools
    ├── opportunities.ts # Sales Pipeline tools
    ├── viewings.ts   # Showing Lifecycle tools
    ├── tasks.ts      # Follow-up & Pipeline Management tools
    ├── media.ts      # Media Lifecycle tools
    ├── projects.ts   # Project/Development + relevance search
    ├── offers.ts     # Transaction Lifecycle tools
    ├── contracts.ts  # Transaction close tools
    ├── activities.ts # Activity Tracking (calls, meetings, emails)
    ├── analytics.ts  # qobrix_count, qobrix_top_values, qobrix_top_records, qobrix_aggregate
    ├── deals.ts      # qobrix_deals (flexible Contracts shortcut)
    ├── reports.ts    # qobrix_timeseries (bucketed metric + YoY), qobrix_days_on_market
    ├── pipeline.ts   # qobrix_funnel, qobrix_stale_leads, qobrix_win_loss
    ├── productivity.ts # qobrix_rep_scorecard
    ├── customers.ts  # qobrix_cohort (repeat buyers/sellers/leads)
    ├── cache.ts      # qobrix_cache_stats, qobrix_cache_clear
    ├── audit.ts      # change log / field history / top changers
    └── meta.ts       # Schema discovery + qobrix_search_dsl_help
test-suite/
├── integration.test.mjs  # Live API smoke tests
├── scenarios.test.mjs    # Multi-step CRM scenarios
├── workflows.test.mjs    # RESO workflow coverage
├── cache.test.mjs        # Cache unit tests (incl. search-page keys)
├── relevance.test.mjs    # Boost scoring + DSL help unit tests
├── format.test.mjs       # Output-cap / truncation tests
└── oauth-modes.test.mjs  # Mode B/C auth smoke tests

Как LLM обучается

Сервер обучает LLM на трёх уровнях:

  1. Инструкции сервера — поле instructions верхнего уровня в ответе MCP initialize предоставляет полную модель данных, шесть канонических процессов с рецептами инструментов, синтаксис поиска, стратегии разрешения внешних ключей и известные особенности.

  2. Описания инструментов — описание каждого инструмента включает его роль в каноническом процессе, RESO-эквивалент, проверенные опции include[], сопоставления полей внешних ключей, форму ответа и примеры поиска. Инструменты релевантного поиска документируют двухуровневый рецепт search + boost; qobrix_search_dsl_help предоставляет полный DSL по запросу.

  3. Описания параметров — Zod-схемы предоставляют справку по каждому параметру с конкретными примерами, допустимыми значениями перечислений и перекрёстными ссылками на другие инструменты.


Технологии

Компонент

Технология

Среда выполнения

Node.js ≥ 20

Язык

TypeScript 5.7

MCP SDK

@modelcontextprotocol/sdk 1.26

Валидация

Zod 3.24

Опциональный кэш

redis 4.x (node-redis), когда задан QOBRIX_REDIS_URL

Транспорт

stdio (по умолчанию) · Streamable HTTP (режимы B / C)

Аутентификация API

Режим A/B: X-Api-User + X-Api-Key · Режим C: Enterprise OAuth с самообслуживанием (URL /connect)

Тестирование

Встроенный в Node.js тестовый раннер (node:test)

Лицензия

Apache License 2.0 — авторские права 2025–2026 SharpSir Group

Режимы A и B включены в этот пакет с открытым исходным кодом. Режим C работает совместно с сервером авторизации Enterprise OAuth от Sharp (SSO / идентификация каждого пользователя) — отдельный коммерческий продукт, поставляемый по запросу — sharpsir.group · dev@sharpsir.group.


Install Server
A
license - permissive license
A
quality
A
maintenance

Maintenance

Maintainers
Response time
4dRelease cycle
8Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    Not graded
    quality
    A
    maintenance
    A comprehensive Model Context Protocol server for real estate data management that provides tools and resources for property listings, agent management, market analysis, client relationships, and area intelligence.
    52
    AGPL 3.0
  • A
    license
    A
    quality
    C
    maintenance
    Read-only MCP server for the Daktela contact center REST API, providing 40 tools to access tickets, calls, emails, chats, contacts, CRM records, campaigns, and real-time agent status.
    45
    1
    MIT
  • A
    license
    C
    quality
    D
    maintenance
    Enterprise-level MCP server integrating with Vista CRM (Loft Edition) for real estate operations, offering 40+ tools for property search, pipeline management, lead capture, and agenda control.
    42
    MIT
  • F
    license
    Not graded
    quality
    C
    maintenance
    MCP server for Moody's Commercial Real Estate API, providing 37 tools for property lookups, market analytics, comps, CMBS data, tax records, and more.

View all related MCP servers

Related MCP Connectors

  • RealEstateAPI MCP — property search, detail, and skip-trace (realestateapi.com)

  • Read-only MCP server for ClassQuill, a tutoring-business-management platform.

  • 350+ production-ready APIs through one MCP server — weather, geocoding, validation, financial data.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/gca-ltd/qobrix-crm-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server