Matchai Docs

Public tools

Reference for the Matchai MCP tools search_listings, get_listing and get_professional. Inputs, outputs, examples and the listing-card widget.

The MCP server offers three tools. All of them are read-only, need no account, and return published data only.

ToolPurpose
search_listingsFind available listings by place, price, bedrooms, bathrooms, property type, and sale or rent.
get_listingGet the full public details of one listing from any of its addresses or from its id.
get_professionalGet a broker's public profile and their available listings.

How the tools behave

  • Read-only. Every tool is annotated readOnlyHint: true, destructiveHint: false, idempotentHint: true and openWorldHint: false. They only read Matchai's own published catalogue.
  • Three parts in every result. content is plain text a model can quote. structuredContent is typed data that matches the tool's outputSchema. _meta is for the listing-card widget and can be ignored by other clients.
  • Unknown means null. A fact that the broker did not state is null, never 0. A listing with no stated price has price: null.
  • Forgiving arguments. null values and empty strings are dropped, and numbers sent as strings, such as "600000" or "$600,000", are converted before validation.
  • Errors a model can fix come back as a result with isError: true and a message. A call that names an unknown tool, or whose arguments is not an object, is a JSON-RPC error -32602. See errors.

The listing object

search_listings and get_professional return listing objects, and get_listing returns the same object with extra detail fields.

Field

Type

search_listings

Searches published listings that are available now. It returns up to 10, best match first.

Input

Every field is optional. With no arguments, the most recently updated listings are returned.

Field

Type

query is read with the same parser as listing search: prices, bedrooms, bathrooms, sale or rent and property type are pulled out of the sentence, in English, French or Spanish. An explicit argument always wins over what the sentence says, and the sentence fills in whatever the arguments leave out. If minPrice is higher than maxPrice, the two are swapped.

Output

Field

Type

The text in content starts with the number of listings and a statement of how they are ordered. It then lists one entry per listing with the title, price and type, the facts, the place, the listing broker and the URL.

An empty result says whether Matchai checked every listing or only the most recently updated ones. It never reports "none exist" for a search that did not reach further back. A city or a price range lets the search look further.

Example

Send this as a tools/call request:

{
  "jsonrpc": "2.0",
  "id": 3,
  "method": "tools/call",
  "params": {
    "name": "search_listings",
    "arguments": { "query": "3 bedroom condo in Laval under 600k" }
  }
}

An abridged result. This search matched one listing, and the filters object shows how the sentence was read:

{
  "content": [
    {
      "type": "text",
      "text": "1 published listing on Matchai. Results are ordered by relevance to the request and by how recently the listing was updated. No broker can pay to change the order or to be included.\n\n1. Bright 3-bedroom condo near Montmorency metro — $585,000, condo for sale\n   3 bedrooms · 1.5 bathrooms · 1,120 sq ft · Montmorency, Laval, Québec\n   Listed by Alice Tremblay (Agence Exemple)\n   https://alice.matchai.co/bright-condo-montmorency"
    }
  ],
  "structuredContent": {
    "kind": "listings",
    "filters": {
      "keywords": ["laval"],
      "city": null,
      "neighbourhood": null,
      "transaction": null,
      "propertyType": "condo",
      "minPrice": null,
      "maxPrice": 600000,
      "minBedrooms": 3,
      "minBathrooms": null
    },
    "count": 1,
    "listings": [
      {
        "id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
        "title": "Bright 3-bedroom condo near Montmorency metro",
        "url": "https://alice.matchai.co/bright-condo-montmorency",
        "price": 585000,
        "currency": "CAD",
        "priceText": "$585,000",
        "transaction": "sale",
        "status": "available",
        "propertyType": "condo",
        "bedrooms": 3,
        "bathrooms": 1.5,
        "livingAreaSqft": 1120,
        "neighbourhood": "Montmorency",
        "city": "Laval",
        "region": "Québec",
        "location": "Montmorency, Laval, Québec",
        "image": "https://media.example.com/listings/bright-condo-montmorency/cover.jpg",
        "broker": { "name": "Alice Tremblay", "brokerage": "Agence Exemple" },
        "site": { "name": "Alice Tremblay Immobilier", "url": "https://alice.matchai.co" },
        "updatedAt": "2026-10-12T14:03:22.000Z"
      }
    ]
  },
  "_meta": {
    "ui": { "resourceUri": "ui://matchai/listing-cards.html?v=3f9a1c2b7d10" }
  }
}

The real _meta object has a few more keys for the widget. The names, addresses and photo host in these examples are made up.

get_listing

Returns the full public details of one published listing.

Input

Send url or id. If you send both, id is used.

Field

Type

These addresses all name the same listing, with or without a trailing slash or tracking parameters:

  • the broker's Matchai Site, such as https://alice.matchai.co/bright-condo-montmorency;
  • the older form with /listing/ before the slug, such as https://alice.matchai.co/listing/bright-condo-montmorency;
  • the broker's own domain, when the site has one;
  • the path form on the platform, such as https://matchai.co/site/alice/bright-condo-montmorency;
  • the Markdown copy of any of these, ending in .md;
  • the bare listing id.

Output

Field

Type

The extra fields on listing:

Field

Type

Search returns available listings only. get_listing can also return a published listing that has since been sold or rented, so check status.

If no published listing matches, the result has isError: true and says that the listing may have been unpublished or that the address may be incomplete.

Example

{
  "name": "get_listing",
  "arguments": { "url": "https://alice.matchai.co/bright-condo-montmorency" }
}

The structuredContent of the result, abridged:

{
  "kind": "listing",
  "listing": {
    "id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
    "title": "Bright 3-bedroom condo near Montmorency metro",
    "url": "https://alice.matchai.co/bright-condo-montmorency",
    "price": 585000,
    "currency": "CAD",
    "priceText": "$585,000",
    "transaction": "sale",
    "status": "available",
    "propertyType": "condo",
    "bedrooms": 3,
    "bathrooms": 1.5,
    "livingAreaSqft": 1120,
    "neighbourhood": "Montmorency",
    "city": "Laval",
    "region": "Québec",
    "location": "Montmorency, Laval, Québec",
    "image": "https://media.example.com/listings/bright-condo-montmorency/cover.jpg",
    "broker": { "name": "Alice Tremblay", "brokerage": "Agence Exemple" },
    "site": { "name": "Alice Tremblay Immobilier", "url": "https://alice.matchai.co" },
    "updatedAt": "2026-10-12T14:03:22.000Z",
    "description": "A bright corner unit on the fourth floor, five minutes from the metro. …",
    "highlights": ["Two balconies", "Indoor parking", "Five minutes from the metro"],
    "yearBuilt": 2012,
    "lotSizeSqft": null,
    "address": null,
    "postalCode": null,
    "images": [
      "https://media.example.com/listings/bright-condo-montmorency/cover.jpg",
      "https://media.example.com/listings/bright-condo-montmorency/living-room.jpg"
    ],
    "datePosted": "2026-09-30"
  }
}

Here the broker did not publish the street address, so address and postalCode are null.

get_professional

Returns a broker's public profile with their available listings, up to 10.

Input

Send username or url. If you send both, username is used.

Field

Type

Output

Field

Type

The fields of professional:

Field

Type

A broker is returned only if they chose to be public somewhere: a published site, a published Matchai Page or an enabled business card. Otherwise the result has isError: true and says that no broker with a public Matchai profile matches.

Example

{
  "name": "get_professional",
  "arguments": { "username": "alice_tremblay" }
}

The professional part of the result's structuredContent. The listings array next to it holds listing objects like those in search_listings.

{
  "name": "Alice Tremblay",
  "username": "alice_tremblay",
  "jobTitle": "Real estate broker",
  "brokerage": "Agence Exemple",
  "licence": { "number": "123456", "body": "OACIQ" },
  "photo": "https://media.example.com/avatars/alice-tremblay.jpg",
  "siteUrl": "https://alice.matchai.co",
  "pageUrl": "https://alice.matchai.pro",
  "contact": { "email": null, "phone": null }
}

The listing-card widget

When a tool returns listings, assistants that support MCP Apps can show them as cards inside the conversation. The cards come from one resource that every tool points to.

DetailValue
URIui://matchai/listing-cards.html?v=…, where v is a version that changes whenever the widget changes
Typetext/html;profile=mcp-app
Namelisting-cards (title "Listing cards")
Referenced from_meta.ui.resourceUri on each tool in tools/list and on each result. ChatGPT reads the same URI from its own key in _meta.

Read the current URI from tools/list instead of hard-coding it. resources/read also accepts the URI without v, and any older v, and answers with the current widget.

resources/list returns the one resource, including the content security policy the assistant should apply:

{
  "resources": [
    {
      "uri": "ui://matchai/listing-cards.html?v=3f9a1c2b7d10",
      "name": "listing-cards",
      "title": "Listing cards",
      "description": "Interactive cards for the listings a Matchai tool returned.",
      "mimeType": "text/html;profile=mcp-app",
      "_meta": {
        "ui": {
          "csp": {
            "connectDomains": ["https://matchai.co"],
            "resourceDomains": ["https://matchai.co", "https://media.example.com"]
          },
          "prefersBorder": true
        }
      }
    }
  ]
}

resources/read returns the widget as one self-contained HTML document in contents[0].text. It uses no framework and no external font or script.

What the widget does:

  • Shows the result by type. kind: "listings" becomes a scrolling row of cards, kind: "listing" becomes one larger card with a short description, and kind: "professional" becomes the broker's name, role and a Visit website link above a row of cards.
  • Follows the assistant. It uses the assistant's colour theme and language (English, French or Spanish) and opens links through the assistant.
  • Handles failure. A result with isError: true, or no structuredContent, shows "Nothing to show".
  • Reports that a card was seen. When a card has been on screen long enough to be read, the widget tells Matchai which listings were visible, for how long and how much of each, and the assistant's coarse platform (web, desktop or mobile). If the result carries no token for this report, nothing is sent. It never sends conversation text or a user identifier.

An assistant that does not render MCP Apps ignores the widget. The text in content and the data in structuredContent carry the whole answer. If you build your own cards, link each one to the listing's url.

On this page