Skip to main content
Glama
chrischall

booli-mcp

by chrischall

booli-mcp

An MCP server for Booli, the Swedish property portal — search active for-sale listings, sold prices (slutpriser), resolve areas, and compute market statistics, all from Claude.

Developed and maintained by AI (Claude Code). Use at your own discretion and within booli.se's terms of use.

How it works

Booli fronts www.booli.se — including its GraphQL API — with a Cloudflare bot wall that blocks server-side clients. booli-mcp therefore reads Booli's consumer GraphQL API by routing each query through your own signed-in www.booli.se browser tab via the fetchproxy bridge (the Transporter extension), reusing your Cloudflare-cleared session. No Booli login is required — just a normal page view. All tools are read-only.

BOOLI_TRANSPORT selects the path: auto (default — direct fetch first, browser-bridge fallback when walled), fetchproxy (always the bridge), or direct. The fetchproxy fleet shares WS port 37149 (BOOLI_WS_PORT).

Related MCP server: Idealista7 MCP Server

Setup

  1. Install the Transporter (fetchproxy) browser extension and keep a www.booli.se tab open.

  2. On the first request, approve the one-time pairing prompt in Transporter.

  3. Run booli_healthcheck to confirm the path is working. Its transport field says which leg served the probe (direct or fetchproxy) and, once the bridge exists, bridge.session_state says whether the Transporter extension is linked, pair_pending (approve the pair code it names), or extension_disconnected.

Install

// mcp config
{
  "mcpServers": {
    "booli": {
      "command": "npx",
      "args": ["-y", "@chrischall/booli-mcp"]
    }
  }
}

Tools

Tool

What it does

booli_search_areas

Resolve a place name to Booli area ids

booli_search_listings

Search active for-sale listings by area + filters

booli_get_listing

Full detail for one property (active or sold) by residence id

booli_search_sold

Search sold listings (slutpriser) with final prices

booli_market_stats

Median/average sold-price statistics for an area

booli_healthcheck

Probe the data path and report transport (direct / fetchproxy, the BOOLI_TRANSPORT mode) and, once the bridge is up, bridge (role, port, extension link session_state, pending pair code) with a next-step hint

Searches scope by area_id (from booli_search_areas) or a free-text location. Money is SEK, areas m². See docs/BOOLI-API.md for the underlying GraphQL API.

Development

npm install
npm test          # vitest, no network
npm run build     # tsc + esbuild bundle

License

MIT

Available Tools

6 tools
booli_get_listingGet a Booli propertyA
Read-onlyIdempotent

Full detail for one property by its Booli residence id — the number in a booli.se/bostad/ URL, or the residence_id from a search result. Works for both active and sold properties. Read-only.

ParametersJSON Schema
NameRequiredDescriptionDefault
viewNoResponse shape: "compact" (default) drops fields the response already carries elsewhere; "full" returns every field this server understands. compact returns the slim PropertySummary/detail projection; "full" returns Booli's whole GraphQL node.
residence_idYesThe property's residence id (e.g. "4370936" from /bostad/4370936).

TDQS

A4.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and openWorldHint, so the safety profile is covered. The description reinforces 'Read-only' and adds the useful behavioral detail that both active and sold properties are supported, but it does not add substantial new behavioral context beyond that.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three short sentences with no filler. The core purpose is front-loaded, and every sentence earns its place by conveying scope, input origin, or safety.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple single-resource getter, this is complete: it names the required identifier, defines its provenance, notes optional response shape via the view parameter, and states applicability to active and sold properties. An output schema is absent, but the description's 'full detail' plus the view parameter documentation is sufficient for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description adds a small but real semantic cue by explaining that residence_id can come from either a booli.se/bostad/<id> URL or a search result's residence_id field, which helps the agent source the value correctly.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'Full detail for one property by its Booli residence id.' It clearly identifies the lookup key and distinguishes this from the sibling search/stats/health tools, which do different jobs.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It tells the agent the precondition for use: the agent must already have a Booli residence id, either from a URL or a search result. It also clarifies that the tool works for both active and sold properties. It does not explicitly name alternative tools for cases where no id is available, but the context and sibling names make this reasonably clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

booli_healthcheckVerify the fetchproxy bridge end-to-endA
Read-onlyIdempotent

Round-trips a small public www.booli.se URL (/graphql) through the fetchproxy bridge and returns diagnostics: the bridge's role (host/peer/null), port, version, the extension link (linked / pair pending / not attached / never answered), the elapsed round-trip time, and a plain-English hint distinguishing 'bridge never came up' from 'extension not connected' from 'real www.booli.se-side problem'. Read-only, no auth required. Call this when a real tool fails and you want to know which hop broke.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description says 'Read-only, no auth required', which adds useful safety/auth context beyond the readOnlyHint and idempotentHint annotations. It also discloses the network round-trip behavior and the specific diagnostics returned, giving the agent a clear model of what the call will and will not do.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single detailed sentence followed by a usage directive. The enumerated diagnostics are useful rather than padded, and the 'Call this when...' guidance is placed at the end. It is slightly long but every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no parameters, no output schema, and annotations already covering read-only and idempotency, the description carries the full explanatory burden and meets it. It explains the purpose, the behavior, the expected diagnostics, authentication, and the concrete failure scenario in which the tool should be used.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters and the schema is empty, so the baseline of 4 applies. The description adds no parameter detail, but none is needed because there is nothing to configure.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific action and resource: round-tripping a small public www.booli.se URL through the fetchproxy bridge and returning diagnostics. It clearly differentiates the tool from the search/get sibling tools, which target listings and areas rather than bridge health.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It states an explicit trigger: 'Call this when a real tool fails and you want to know which hop broke.' It does not name when-not-to-use or alternative tools, but the healthcheck's role is sufficiently distinct from the sibling search tools that the guidance is clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

booli_market_statsBooli sold-price market statisticsA
Read-only

Aggregate sold-price statistics (median/average final price, price per m², average over/under-asking %) for an area on booli.se. Takes the same scope and filters as booli_search_sold, over one page of sold results. Check sample_size before trusting a thin median. Read-only.

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNo1-based page (default 1).
sortNoSort key (default: soldDate — most recent sales first with ascending false).
viewNoResponse shape: "compact" (default) drops fields the response already carries elsewhere; "full" returns every field this server understands. compact returns the slim PropertySummary/detail projection; "full" returns Booli's whole GraphQL node.
area_idNoBooli area id from booli_search_areas. Provide this OR `location`.
locationNoFree-text place name (e.g. "Nacka", "Södermalm") resolved to its top Booli area. Ignored when `area_id` is set.
ascendingNoSort ascending (default false).
max_roomsNo
min_roomsNo
object_typeNoProperty type(s), comma-separated, from: Lägenhet, Villa, Kedjehus-Parhus-Radhus, Fritidshus, Gård, Tomt/Mark.
max_plot_areaNom²
max_sold_dateNoLatest sold date, YYYYMMDD.
min_plot_areaNom²
min_sold_dateNoEarliest sold date, YYYYMMDD (e.g. "20240101").
max_sold_priceNoSEK
min_sold_priceNoSEK
max_living_areaNom²
min_living_areaNom²
max_sold_sqm_priceNoSEK/m²
min_sold_sqm_priceNoSEK/m²
is_new_constructionNotrue = only new production; false = exclude new production.
max_construction_yearNo
min_construction_yearNo

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark readOnlyHint=true, so the description's 'Read-only' is redundant. However, it adds valuable behavioral context: the tool operates over exactly one page of results and warns about sample_size affecting median reliability. These are not derivable from annotations or schema, so they meaningfully disclose behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences, front-loads the purpose, and includes the key caveat about sample_size. Every sentence carries meaning with no filler or repetition of schema details. It is appropriately concise for the tool's complexity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool has 22 parameters, no output schema, and is a read-only aggregation, the description is sufficient. It explains what it returns, its relationship to booli_search_sold, and a practical trust caveat. It does not detail return structure or pagination beyond one page, but that is reasonably implied. For an aggregation tool with this complexity, it is well-rounded.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is high (82%), so the schema already documents most parameters. The description adds no per-parameter detail, but it references that the tool shares the same filters as booli_search_sold, which implies parameter reuse. Since the schema covers the parameters, a baseline of 3 is appropriate; the description adds marginal value beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb ('Aggregate') and a clear resource ('sold-price statistics'), and explicitly lists the derived metrics (median/average final price, price per m², average over/under-asking %). It also differentiates from sibling tools by referencing booli_search_sold as the scope basis, so an agent can distinguish it from listing retrieval.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It states the tool takes 'the same scope and filters as booli_search_sold', giving clear context on when to use it (for aggregate stats on a page of sold results). It also adds a practical tip ('Check sample_size before trusting a thin median'). It does not explicitly name alternatives or exclusions, but the reference to booli_search_sold implicitly routes away from listing tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

booli_search_areasResolve a Booli areaA
Read-onlyIdempotent

Resolve a place name to Booli areas — municipalities, districts, streets — each with its area_id to pass as area_id into booli_search_listings / booli_search_sold. Read-only.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMax results (default 10).
queryYesPlace-name search string (e.g. "Nacka", "Södermalm").

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already cover safety with readOnlyHint, idempotentHint, and openWorldHint, lowering the bar. The description adds some behavioral context by specifying that it returns municipalities, districts, and streets each with an `area_id`, but 'Read-only' merely repeats what readOnlyHint already declares. It does not disclose ambiguity handling, multiple match behavior, or other runtime quirks.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core sentence is dense, front-loaded, and contains the essential purpose, output types, and downstream usage in one line. The trailing 'Read-only.' is redundant with the annotations but is harmless; the overall definition is compact and efficient.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple two-parameter resolver with safe annotations, the description is largely complete: it explains the input, the output types, and how the output is consumed by sibling tools. Because there is no output schema, it would be slightly stronger to state what happens on no match or how many areas may be returned, but the essential calling context is present.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already explains both `query` and `limit`. The description reinforces that `query` is a place name and that the result carries `area_id`, but it does not add meaningful parameter-level detail beyond what the input schema provides, so the baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Resolve') plus a clear resource ('place name to Booli areas') and names the concrete output types: municipalities, districts, streets. It also differentiates the tool by stating that the resulting `area_id` feeds into booli_search_listings / booli_search_sold, so an agent can distinguish it from its siblings without opening their schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear context for when to use the tool: resolving a place name before searching listings or sold data via the returned `area_id`. It names the downstream tools, which implies the intended workflow, but it does not explicitly state when not to use this tool or name a direct alternative.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

booli_search_listingsSearch Booli for-sale listingsA
Read-only

Search active for-sale property listings on booli.se. Scope by area_id (from booli_search_areas) or a free-text location, and filter by price, rooms, living area, plot, object type, construction year. Paginated by page; check total_count/pages. Read-only.

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNo1-based page (default 1).
sortNoSort key (default: newest published).
viewNoResponse shape: "compact" (default) drops fields the response already carries elsewhere; "full" returns every field this server understands. compact returns the slim PropertySummary/detail projection; "full" returns Booli's whole GraphQL node.
area_idNoBooli area id from booli_search_areas. Provide this OR `location`.
locationNoFree-text place name (e.g. "Nacka", "Södermalm") resolved to its top Booli area. Ignored when `area_id` is set.
ascendingNoSort ascending (default false).
max_roomsNo
min_roomsNo
object_typeNoProperty type(s), comma-separated, from: Lägenhet, Villa, Kedjehus-Parhus-Radhus, Fritidshus, Gård, Tomt/Mark.
max_plot_areaNom²
min_plot_areaNom²
max_list_priceNoSEK
min_list_priceNoSEK
max_living_areaNom²
min_living_areaNom²
max_list_sqm_priceNoSEK/m²
min_list_sqm_priceNoSEK/m²
is_new_constructionNotrue = only new production; false = exclude new production.
max_construction_yearNo
min_construction_yearNo

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, and the description reinforces this with 'Read-only.' It adds behavioral context beyond annotations by describing pagination ('Paginated by `page`; check `total_count`/`pages`') and the scoping rule ('area_id ... OR location'). No contradictions; the description complements the annotations with operational detail.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, no wasted words. The purpose is stated first, then scoping, then filters, then pagination. Every clause earns its place. The structure is front-loaded with the most important information and reads naturally.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 20-parameter search tool with no output schema, the description covers the core behaviors: what it searches, how to scope, what filters exist, and how pagination works. It references a sibling for area_id resolution. It doesn't mention authentication or rate limits, but those are not essential for selection. The description is sufficient for an agent to call it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 80%, so the baseline is 3. The description adds value by explaining the relationship between area_id and location (location ignored when area_id is set), and by grouping filters by category (price, rooms, living area, etc.). It also clarifies that area_id comes from booli_search_areas, which is not in the schema. This goes beyond the schema's per-parameter descriptions, warranting a 4.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a precise verb+resource: 'Search active for-sale property listings on booli.se.' It distinguishes itself from siblings by the 'active for-sale' qualifier, which sets it apart from booli_search_sold (sold listings), booli_get_listing (single listing), and the others. An agent can tell exactly what this tool does and when to reach for it.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear context: it's for active for-sale listings, and it even references booli_search_areas for obtaining area_id. It implies the 'when' (when you need active listings) but does not explicitly state exclusions like 'use booli_search_sold for sold listings.' However, the 'active' qualifier and the sibling names make the usage boundary evident, so it's clear enough without being exhaustive.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

booli_search_soldSearch Booli sold listings (slutpriser)A
Read-only

Search sold properties (slutpriser) on booli.se with the achieved final price and over/under-asking % — the comparables for valuation. Scope by area_id or free-text location, filter by sold price, sold date, rooms, area, object type. Paginated by page. Read-only.

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNo1-based page (default 1).
sortNoSort key (default: soldDate — most recent sales first with ascending false).
viewNoResponse shape: "compact" (default) drops fields the response already carries elsewhere; "full" returns every field this server understands. compact returns the slim PropertySummary/detail projection; "full" returns Booli's whole GraphQL node.
area_idNoBooli area id from booli_search_areas. Provide this OR `location`.
locationNoFree-text place name (e.g. "Nacka", "Södermalm") resolved to its top Booli area. Ignored when `area_id` is set.
ascendingNoSort ascending (default false).
max_roomsNo
min_roomsNo
object_typeNoProperty type(s), comma-separated, from: Lägenhet, Villa, Kedjehus-Parhus-Radhus, Fritidshus, Gård, Tomt/Mark.
max_plot_areaNom²
max_sold_dateNoLatest sold date, YYYYMMDD.
min_plot_areaNom²
min_sold_dateNoEarliest sold date, YYYYMMDD (e.g. "20240101").
max_sold_priceNoSEK
min_sold_priceNoSEK
max_living_areaNom²
min_living_areaNom²
max_sold_sqm_priceNoSEK/m²
min_sold_sqm_priceNoSEK/m²
is_new_constructionNotrue = only new production; false = exclude new production.
max_construction_yearNo
min_construction_yearNo

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already provide readOnlyHint and openWorldHint, and the description reinforces safety with 'Read-only.' It adds useful behavioral context beyond annotations by specifying the result includes achieved final price and over/under-asking %, plus pagination by page. No contradictions with annotations are present.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact and front-loaded with the core purpose before filter details. It earns its place overall, though 'Read-only' repeats the annotation and the single long sentence could be split for slightly easier parsing.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Despite 22 optional parameters and no output schema, the description plus schema covers scope selection, filter dimensions, pagination, and key return fields. An agent can determine how to invoke the tool, though deeper output-shape details are left unspecified.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is high at 82%, so the baseline is 3. The description adds a helpful high-level grouping of scope by area_id/location and filter categories, but it does not add substantial new parameter meaning beyond what the schema already documents for the remaining parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: searching sold properties (slutpriser) on booli.se. It also adds distinguishing scope by mentioning achieved final price and over/under-asking %, positioning it as the comparables tool next to siblings like booli_search_listings and booli_market_stats.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'the comparables for valuation' gives clear context for when this tool is the right choice. It does not explicitly name alternatives or exclusion conditions, but the sold-property framing strongly separates it from active listing or stats siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 2 tool updatesv2.1.3
    • Changedbooli_market_stats2 fields changed
      • changedInput schema / properties / sort / description
        Previous value: -"Sort key (default: newest published)."New value: +"Sort key (default: soldDate — most recent sales first with ascending false)."
      • changedInput schema / properties / sort / enum
        Previous value: -[
        -  "published",
        -  "listPrice",
        -  "listSqmPrice",
        -  "rooms",
        -  "livingArea",
        -  "rent",
        -  "plotArea"
        -]New value: +[
        +  "published",
        +  "listPrice",
        +  "listSqmPrice",
        +  "rooms",
        +  "livingArea",
        +  "rent",
        +  "plotArea",
        +  "soldDate",
        +  "soldPrice"
        +]
    • Changedbooli_search_sold2 fields changed
      • changedInput schema / properties / sort / description
        Previous value: -"Sort key (default: newest published)."New value: +"Sort key (default: soldDate — most recent sales first with ascending false)."
      • changedInput schema / properties / sort / enum
        Previous value: -[
        -  "published",
        -  "listPrice",
        -  "listSqmPrice",
        -  "rooms",
        -  "livingArea",
        -  "rent",
        -  "plotArea"
        -]New value: +[
        +  "published",
        +  "listPrice",
        +  "listSqmPrice",
        +  "rooms",
        +  "livingArea",
        +  "rent",
        +  "plotArea",
        +  "soldDate",
        +  "soldPrice"
        +]
  2. 6 tool updatesv2.0.0
    • Changedbooli_get_listing1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedbooli_healthcheck1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedbooli_market_stats1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedbooli_search_areas1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedbooli_search_listings1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedbooli_search_sold1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
  3. 4 tool updatesv1.3.1
    • Changedbooli_get_listing2 fields changed
      • removedInput schema / properties / compact
        Removed value: -{
        -  "description": "Return a slim summary instead of the full raw record (default false).",
        -  "type": "boolean"
        -}
      • addedInput schema / properties / view
        Added value: +{
        +  "description": "Response shape: \"compact\" (default) drops fields the response already carries elsewhere; \"full\" returns every field this server understands. compact returns the slim PropertySummary/detail projection; \"full\" returns Booli's whole GraphQL node.",
        +  "enum": [
        +    "compact",
        +    "full"
        +  ],
        +  "type": "string"
        +}
    • Changedbooli_market_stats2 fields changed
      • removedInput schema / properties / compact
        Removed value: -{
        -  "description": "Return slim summary records (default true). Set false for full raw fields.",
        -  "type": "boolean"
        -}
      • addedInput schema / properties / view
        Added value: +{
        +  "description": "Response shape: \"compact\" (default) drops fields the response already carries elsewhere; \"full\" returns every field this server understands. compact returns the slim PropertySummary/detail projection; \"full\" returns Booli's whole GraphQL node.",
        +  "enum": [
        +    "compact",
        +    "full"
        +  ],
        +  "type": "string"
        +}
    • Changedbooli_search_listings2 fields changed
      • removedInput schema / properties / compact
        Removed value: -{
        -  "description": "Return slim summary records (default true). Set false for full raw fields.",
        -  "type": "boolean"
        -}
      • addedInput schema / properties / view
        Added value: +{
        +  "description": "Response shape: \"compact\" (default) drops fields the response already carries elsewhere; \"full\" returns every field this server understands. compact returns the slim PropertySummary/detail projection; \"full\" returns Booli's whole GraphQL node.",
        +  "enum": [
        +    "compact",
        +    "full"
        +  ],
        +  "type": "string"
        +}
    • Changedbooli_search_sold2 fields changed
      • removedInput schema / properties / compact
        Removed value: -{
        -  "description": "Return slim summary records (default true). Set false for full raw fields.",
        -  "type": "boolean"
        -}
      • addedInput schema / properties / view
        Added value: +{
        +  "description": "Response shape: \"compact\" (default) drops fields the response already carries elsewhere; \"full\" returns every field this server understands. compact returns the slim PropertySummary/detail projection; \"full\" returns Booli's whole GraphQL node.",
        +  "enum": [
        +    "compact",
        +    "full"
        +  ],
        +  "type": "string"
        +}
  4. 6 tool updatesv1.0.0
    • Changedbooli_get_listing3 fields changed
      • removedInput schema / properties / booli_id
        Removed value: -{
        -  "description": "The listing's Booli id (e.g. \"1579812\").",
        -  "type": "string"
        -}
      • addedInput schema / properties / residence_id
        Added value: +{
        +  "description": "The property's residence id (e.g. \"4370936\" from /bostad/4370936).",
        +  "type": "string"
        +}
      • changedInput schema / required
        Previous value: -[
        -  "booli_id"
        -]New value: +[
        +  "residence_id"
        +]
    • Removedbooli_get_sold
    • Changedbooli_market_stats13 fields changed
      • changedInput schema / properties / area_id / description
        Previous value: -"Booli area id(s) from booli_search_areas, comma-separated for several (e.g. \"76,16\")."New value: +"Booli area id from booli_search_areas. Provide this OR `location`."
      • addedInput schema / properties / ascending
        Added value: +{
        +  "description": "Sort ascending (default false).",
        +  "type": "boolean"
        +}
      • removedInput schema / properties / bbox
        Removed value: -{
        -  "description": "Bounding box \"lat_lo,lng_lo,lat_hi,lng_hi\" (SW then NE corner).",
        -  "type": "string"
        -}
      • removedInput schema / properties / center
        Removed value: -{
        -  "description": "Coordinate \"lat,lng\" (e.g. \"59.34674,18.0603\"); use with `dim`.",
        -  "type": "string"
        -}
      • removedInput schema / properties / dim
        Removed value: -{
        -  "description": "Rectangle size in metres \"w,h\" (e.g. \"400,500\"), used with `center`.",
        -  "type": "string"
        -}
      • removedInput schema / properties / limit
        Removed value: -{
        -  "description": "Default 30, max 100.",
        -  "maximum": 100,
        -  "minimum": 1,
        -  "type": "integer"
        -}
      • addedInput schema / properties / location
        Added value: +{
        +  "description": "Free-text place name (e.g. \"Nacka\", \"Södermalm\") resolved to its top Booli area. Ignored when `area_id` is set.",
        +  "type": "string"
        +}
      • removedInput schema / properties / max_rent
        Removed value: -{
        -  "description": "SEK/month",
        -  "minimum": 0,
        -  "type": "number"
        -}
      • changedInput schema / properties / object_type / description
        Previous value: -"Property type(s), comma-separated, from: villa, lägenhet, gård, tomt-mark, fritidshus, parhus, radhus, kedjehus."New value: +"Property type(s), comma-separated, from: Lägenhet, Villa, Kedjehus-Parhus-Radhus, Fritidshus, Gård, Tomt/Mark."
      • removedInput schema / properties / offset
        Removed value: -{
        -  "description": "Pagination offset.",
        -  "maximum": 9007199254740991,
        -  "minimum": 0,
        -  "type": "integer"
        -}
      • addedInput schema / properties / page
        Added value: +{
        +  "description": "1-based page (default 1).",
        +  "maximum": 9007199254740991,
        +  "minimum": 1,
        +  "type": "integer"
        +}
      • removedInput schema / properties / q
        Removed value: -{
        -  "description": "Free-text area search (e.g. \"Nacka\", \"Södermalm\"). One of q / area_id / center / bbox scopes the search.",
        -  "type": "string"
        -}
      • addedInput schema / properties / sort
        Added value: +{
        +  "description": "Sort key (default: newest published).",
        +  "enum": [
        +    "published",
        +    "listPrice",
        +    "listSqmPrice",
        +    "rooms",
        +    "livingArea",
        +    "rent",
        +    "plotArea"
        +  ],
        +  "type": "string"
        +}
    • Changedbooli_search_areas8 fields changed
      • removedInput schema / properties / lat
        Removed value: -{
        -  "description": "Latitude; use together with `lng`.",
        -  "type": "number"
        -}
      • changedInput schema / properties / limit / description
        Previous value: -"Default 10, max 50."New value: +"Max results (default 10)."
      • removedInput schema / properties / lng
        Removed value: -{
        -  "description": "Longitude; use together with `lat`.",
        -  "type": "number"
        -}
      • removedInput schema / properties / only_with_listings
        Removed value: -{
        -  "description": "Only return areas that currently have listings for sale.",
        -  "type": "boolean"
        -}
      • removedInput schema / properties / only_with_sold
        Removed value: -{
        -  "description": "Only return areas that have sold listings.",
        -  "type": "boolean"
        -}
      • removedInput schema / properties / q
        Removed value: -{
        -  "description": "Place-name search string (e.g. \"Nacka\").",
        -  "type": "string"
        -}
      • addedInput schema / properties / query
        Added value: +{
        +  "description": "Place-name search string (e.g. \"Nacka\", \"Södermalm\").",
        +  "type": "string"
        +}
      • addedInput schema / required
        Added value: +[
        +  "query"
        +]
    • Changedbooli_search_listings13 fields changed
      • changedInput schema / properties / area_id / description
        Previous value: -"Booli area id(s) from booli_search_areas, comma-separated for several (e.g. \"76,16\")."New value: +"Booli area id from booli_search_areas. Provide this OR `location`."
      • addedInput schema / properties / ascending
        Added value: +{
        +  "description": "Sort ascending (default false).",
        +  "type": "boolean"
        +}
      • removedInput schema / properties / bbox
        Removed value: -{
        -  "description": "Bounding box \"lat_lo,lng_lo,lat_hi,lng_hi\" (SW then NE corner).",
        -  "type": "string"
        -}
      • removedInput schema / properties / center
        Removed value: -{
        -  "description": "Coordinate \"lat,lng\" (e.g. \"59.34674,18.0603\"); use with `dim`.",
        -  "type": "string"
        -}
      • removedInput schema / properties / dim
        Removed value: -{
        -  "description": "Rectangle size in metres \"w,h\" (e.g. \"400,500\"), used with `center`.",
        -  "type": "string"
        -}
      • removedInput schema / properties / limit
        Removed value: -{
        -  "description": "Default 30, max 100.",
        -  "maximum": 100,
        -  "minimum": 1,
        -  "type": "integer"
        -}
      • addedInput schema / properties / location
        Added value: +{
        +  "description": "Free-text place name (e.g. \"Nacka\", \"Södermalm\") resolved to its top Booli area. Ignored when `area_id` is set.",
        +  "type": "string"
        +}
      • removedInput schema / properties / max_rent
        Removed value: -{
        -  "description": "SEK/month",
        -  "minimum": 0,
        -  "type": "number"
        -}
      • changedInput schema / properties / object_type / description
        Previous value: -"Property type(s), comma-separated, from: villa, lägenhet, gård, tomt-mark, fritidshus, parhus, radhus, kedjehus."New value: +"Property type(s), comma-separated, from: Lägenhet, Villa, Kedjehus-Parhus-Radhus, Fritidshus, Gård, Tomt/Mark."
      • removedInput schema / properties / offset
        Removed value: -{
        -  "description": "Pagination offset.",
        -  "maximum": 9007199254740991,
        -  "minimum": 0,
        -  "type": "integer"
        -}
      • addedInput schema / properties / page
        Added value: +{
        +  "description": "1-based page (default 1).",
        +  "maximum": 9007199254740991,
        +  "minimum": 1,
        +  "type": "integer"
        +}
      • removedInput schema / properties / q
        Removed value: -{
        -  "description": "Free-text area search (e.g. \"Nacka\", \"Södermalm\"). One of q / area_id / center / bbox scopes the search.",
        -  "type": "string"
        -}
      • addedInput schema / properties / sort
        Added value: +{
        +  "description": "Sort key (default: newest published).",
        +  "enum": [
        +    "published",
        +    "listPrice",
        +    "listSqmPrice",
        +    "rooms",
        +    "livingArea",
        +    "rent",
        +    "plotArea"
        +  ],
        +  "type": "string"
        +}
    • Changedbooli_search_sold13 fields changed
      • changedInput schema / properties / area_id / description
        Previous value: -"Booli area id(s) from booli_search_areas, comma-separated for several (e.g. \"76,16\")."New value: +"Booli area id from booli_search_areas. Provide this OR `location`."
      • addedInput schema / properties / ascending
        Added value: +{
        +  "description": "Sort ascending (default false).",
        +  "type": "boolean"
        +}
      • removedInput schema / properties / bbox
        Removed value: -{
        -  "description": "Bounding box \"lat_lo,lng_lo,lat_hi,lng_hi\" (SW then NE corner).",
        -  "type": "string"
        -}
      • removedInput schema / properties / center
        Removed value: -{
        -  "description": "Coordinate \"lat,lng\" (e.g. \"59.34674,18.0603\"); use with `dim`.",
        -  "type": "string"
        -}
      • removedInput schema / properties / dim
        Removed value: -{
        -  "description": "Rectangle size in metres \"w,h\" (e.g. \"400,500\"), used with `center`.",
        -  "type": "string"
        -}
      • removedInput schema / properties / limit
        Removed value: -{
        -  "description": "Default 30, max 100.",
        -  "maximum": 100,
        -  "minimum": 1,
        -  "type": "integer"
        -}
      • addedInput schema / properties / location
        Added value: +{
        +  "description": "Free-text place name (e.g. \"Nacka\", \"Södermalm\") resolved to its top Booli area. Ignored when `area_id` is set.",
        +  "type": "string"
        +}
      • removedInput schema / properties / max_rent
        Removed value: -{
        -  "description": "SEK/month",
        -  "minimum": 0,
        -  "type": "number"
        -}
      • changedInput schema / properties / object_type / description
        Previous value: -"Property type(s), comma-separated, from: villa, lägenhet, gård, tomt-mark, fritidshus, parhus, radhus, kedjehus."New value: +"Property type(s), comma-separated, from: Lägenhet, Villa, Kedjehus-Parhus-Radhus, Fritidshus, Gård, Tomt/Mark."
      • removedInput schema / properties / offset
        Removed value: -{
        -  "description": "Pagination offset.",
        -  "maximum": 9007199254740991,
        -  "minimum": 0,
        -  "type": "integer"
        -}
      • addedInput schema / properties / page
        Added value: +{
        +  "description": "1-based page (default 1).",
        +  "maximum": 9007199254740991,
        +  "minimum": 1,
        +  "type": "integer"
        +}
      • removedInput schema / properties / q
        Removed value: -{
        -  "description": "Free-text area search (e.g. \"Nacka\", \"Södermalm\"). One of q / area_id / center / bbox scopes the search.",
        -  "type": "string"
        -}
      • addedInput schema / properties / sort
        Added value: +{
        +  "description": "Sort key (default: newest published).",
        +  "enum": [
        +    "published",
        +    "listPrice",
        +    "listSqmPrice",
        +    "rooms",
        +    "livingArea",
        +    "rent",
        +    "plotArea"
        +  ],
        +  "type": "string"
        +}
  5. 7 tool updatesv0.0.0
    • First observedbooli_get_listing
    • First observedbooli_get_sold
    • First observedbooli_healthcheck
    • First observedbooli_market_stats
    • First observedbooli_search_areas
    • First observedbooli_search_listings
    • First observedbooli_search_sold

TDQS

A4.3/5.0

Scored across 6 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: detail lookup, active search, sold search, aggregate stats, area resolution, and diagnostics. The only potential overlap between booli_market_stats and booli_search_sold is clearly separated as aggregate versus individual results.

Naming Consistency4/5

All tools share the booli_ prefix and use lowercase snake_case with a verb or descriptive noun. Minor deviations like booli_healthcheck and booli_market_stats not following the strict verb_noun form are slight but do not harm predictability.

Tool Count5/5

Six tools is a well-scoped count for a real-estate data server. Each tool earns its place and there is no redundant bloat or sparse coverage.

Completeness5/5

The surface covers the core read-only domain well: resolving areas, searching active listings, searching sold listings, retrieving listing details, computing market stats, and diagnosing connectivity. No significant gaps are apparent for the stated purpose.

Maintenance

ActivityActive
ResponsivenessResponsive

Related MCP Connectors

Related MCP Servers

  • F
    license
    B
    quality
    Not graded
    maintenance
    Enables AI assistants to search and analyze Swedish real estate data from Booli.se using natural language queries. Supports property searches with comprehensive filtering options and location discovery through GraphQL API integration.
    3
    1
    -
  • A
    license
    C
    quality
    D
    maintenance
    Enables access to Idealista API for searching and retrieving property listings across Spain, Portugal, and Italy. Supports various property types including homes, apartments, garages, commercial properties, offices, and land with detailed filtering options.
    14
    3
    MIT
  • A
    license
    Not graded
    quality
    F
    maintenance
    Provides real-time access to Zillow real estate data, enabling property search, details, Zestimates, market trends, and mortgage calculations via natural language.
    4 npm
    48
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    Enables searching Korean apartment listings, market prices, and recent transactions via Naver Real Estate through natural language.
    6
    MIT