MCP server
Connect an AI client (Claude Desktop, Cursor, or any MCP-compatible tool) to Avensa CRM data and actions via the Model Context Protocol.
Avensa runs a remote MCP server at /api/mcp (Streamable HTTP, stateless JSON mode). It exposes the same tool registry the in-app AI assistant uses, so an external MCP client can read and act on your CRM data with the same tenant isolation and per-tool permission checks the app enforces.
https://api.avensa.bg/api/mcp
Connecting a client
The endpoint requires a Bearer credential — either an API key (pk_live_...) or an OAuth 2.0 access token (oat_...). Most MCP-aware clients (Claude Desktop, Cursor, etc.) support OAuth discovery and will walk you through it automatically:
- Add
https://api.avensa.bg/api/mcpas a remote MCP server in your client. - The client requests
/.well-known/oauth-protected-resource(returned in theWWW-Authenticateheader on a401) and follows the standard OAuth 2.0 Authorization Code + PKCE flow against/api/v1/oauth/authorizeand/api/v1/oauth/token. - You approve the requested scopes for your account; the client stores the resulting
oat_token and sends it asAuthorization: Bearer oat_...on every MCP request.
If your client doesn't support OAuth discovery, create an API key instead (Settings → API, see Authentication and API keys) and paste it as the Bearer token.
Scopes
MCP tokens are granted from the REST API scope vocabulary plus a few MCP-specific domains: contacts, properties, companies, deals, tasks, documents, calendar, viewings, activities, email, inbox, notes, exchange, workflows, analytics (read-only), plus settings:write and members:write for administrative tools. Grant only what the client needs.
Protocol details
- Transport: Streamable HTTP —
POSTwith a JSON-RPC 2.0 body (single message or a batch array, up to 50 messages). AGETfor a server-initiated SSE stream is accepted but declined (this server has no push messages). - If your client sends
Accept: text/event-stream, the response is emitted as a single SSEmessageevent per JSON-RPC response, then the stream closes. - Request body cap: 1 MB.
- Protocol version:
2025-11-25(also accepts2025-06-18).
Available tools
Tools mirror the in-app AI assistant's capabilities: search and read CRM records, and propose CRM writes. High-level groups:
- Contacts — search, create, update, merge, reassign, bulk update.
- Properties — search, create, update, delete, compare, match buyers.
- Deals — search, create, update, stage changes, mark won/lost, commission and financing status.
- Tasks & subtasks — create, update, complete, from templates.
- Calendar & viewings — create/update/cancel events, schedule and optimize viewings, check availability.
- Documents — search, request, link to a record, get signed download URLs.
- Communication — draft email, log calls/communication, suggest follow-ups.
- Automation rules — list, create, toggle, inspect activity.
- Exchange (inter-agency MLS) — search listings, post demands, request cooperation, message.
- Analytics & reporting — dashboard metrics, CRM statistics, owner reports, market analysis.
- Custom fields, saved searches, task templates, team members — supporting CRUD.
Call tools/list for the exact, current tool names and JSON schemas available to your token's scopes — this page intentionally doesn't enumerate every tool name, since the registry is the source of truth and can gain tools between releases.
Writes are two-phase
Every write tool follows the same human-in-the-loop pattern as the in-app assistant: calling a write tool returns a preview of the change plus a proposal_token, with needs_confirmation: true — it does not apply the change. To commit it, call the virtual confirm_action tool with that proposal_token. Read tools run directly with no confirmation step.
// 1. Call a write tool, e.g. create_contact
// → { "needs_confirmation": true, "proposal_token": "...", "preview": { "...": "..." } }
// 2. After the user approves, commit it:
{
"name": "confirm_action",
"arguments": { "proposal_token": "..." }
}
Abuse protection
Before dispatch, the endpoint applies the same layers /api/v1 does:
- Plan gating (an active subscription or trial is required; fails closed on error).
- Per-credential rate limiting, shared with the
/api/v1API-key limiter. - An
api_audit_logsentry for every request (fire-and-forget, never blocks the response).
A 429 response includes Retry-After.