Skip to main content
Glama
jasp-nerd

kamernet-mcp

by jasp-nerd

MCP server for Kamernet.nl: search Dutch rooms, studios and apartments from Claude, Cursor, Codex and any AI agent.

CI PyPI Python License: MIT

English | Nederlands


Finding a room in the Netherlands is brutal: good listings get 60+ replies within the hour. kamernet-mcp puts Kamernet, the largest Dutch platform for rooms, studios and apartments, inside your AI agent. The agent searches with your criteria, reads full listings in English and Dutch, ranks them against your budget, and tells you when something new appears.

kamernet-mcp searching Kamernet live

You:    Find me a furnished room in Utrecht under €900, at least 15 m², and rank
        the top 3 by value for a working professional who needs registration.

Agent:  → search_listings(city="Utrecht", max_rent=900, min_size=15, ...)
        → get_listing(...) ×3
        → score-listing prompt
        Here are the top 3, with deposits, energy labels and red flags…

Quickstart

Requires uv (or plain pip). One command:

claude mcp add kamernet -- uvx kamernet-mcp

Then ask Claude to find you a room. For other clients, use an install badge or unfold yours below.

Install in Cursor Install in VS Code

claude mcp add kamernet -- uvx kamernet-mcp

Or per project, committed to git, in .mcp.json:

{
  "mcpServers": {
    "kamernet": { "command": "uvx", "args": ["kamernet-mcp"] }
  }
}

Add to claude_desktop_config.json (Settings → Developer → Edit Config):

{
  "mcpServers": {
    "kamernet": { "command": "uvx", "args": ["kamernet-mcp"] }
  }
}

Use the install badge above, or add to ~/.cursor/mcp.json (or .cursor/mcp.json in a project):

{
  "mcpServers": {
    "kamernet": { "command": "uvx", "args": ["kamernet-mcp"] }
  }
}
codex mcp add kamernet -- uvx kamernet-mcp

Or add to ~/.codex/config.toml:

[mcp_servers.kamernet]
command = "uvx"
args = ["kamernet-mcp"]

Add to opencode.json (note OpenCode uses an mcp key, not mcpServers):

{
  "mcp": {
    "kamernet": {
      "type": "local",
      "command": ["uvx", "kamernet-mcp"],
      "enabled": true
    }
  }
}

Use the install badge above, or add to .vscode/mcp.json (note VS Code uses a servers key):

{
  "servers": {
    "kamernet": { "type": "stdio", "command": "uvx", "args": ["kamernet-mcp"] }
  }
}

Add to ~/.codeium/windsurf/mcp_config.json:

{
  "mcpServers": {
    "kamernet": { "command": "uvx", "args": ["kamernet-mcp"] }
  }
}

Add to ~/.gemini/settings.json:

{
  "mcpServers": {
    "kamernet": { "command": "uvx", "args": ["kamernet-mcp"] }
  }
}

Add to Zed settings.json:

{
  "context_servers": {
    "kamernet": { "command": { "path": "uvx", "args": ["kamernet-mcp"] } }
  }
}
pip install kamernet-mcp

Then use kamernet-mcp as the command in any of the configs above.

Related MCP server: marktplaats-mcp

Tools

Tool

What it does

search_listings

Search by city with filters: max rent (€), min size (m²), radius (km), property type (room / apartment / studio / anti-squat / student housing), sort order, pagination.

get_listing

Full details of one listing: bilingual description, rent + deposit, energy label, registration ("inschrijving") possibility, landlord stats (response rate, member since, verified badges), photos, coordinates.

get_new_listings

Stateless monitoring: "what appeared since my last check?" Lets your agent poll without hammering the site.

account_status*

Verify the configured Kamernet account can log in.

reply_to_listing*

Experimental: sends a reply to a landlord from your account, including Kamernet's applicant questions.

* Only registered when KAMERNET_EMAIL / KAMERNET_PASSWORD are set; see Authenticated tools.

There is also a kamernet://filters resource listing all valid filter values, and a score-listing prompt: a weighted rubric (price, location, quality, privacy, long-term fit) with bilingual deal-breaker detection ("no internationals" / "geen internationals") that your agent uses to rank listings for you.

Configuration

Everything works with zero config. Optional environment variables:

Variable

Default

Purpose

KAMERNET_EMAIL

Enables authenticated tools.

KAMERNET_PASSWORD

Enables authenticated tools.

KAMERNET_REQUEST_DELAY

1.0

Minimum seconds between requests to kamernet.nl. Values below 1.0 are ignored.

KAMERNET_MAX_REPLIES_PER_SESSION

50

Hard cap on automated replies per server session.

KAMERNET_USER_AGENT

transparent UA

Identifies this tool to Kamernet, with a link to this repo.

Authenticated tools (experimental)

Searching needs no account. Replying to landlords requires a paid Kamernet premium account (that's Kamernet's paywall, not ours) and browser automation:

uvx --with 'kamernet-mcp[auth]' kamernet-mcp   # or: pip install 'kamernet-mcp[auth]'
playwright install chromium

Set KAMERNET_EMAIL and KAMERNET_PASSWORD in your MCP client's env block. Cookies are cached locally so login happens rarely.

WARNING

Automated replying violates Kamernet's terms of service and can get your account banned. Replies are hard-capped per session. Use it for messages you wrote and approved for one specific listing; a generic message sent to 50 landlords floods landlords and hurts your own chances. Use at your own risk.

How it works

Kamernet is a Next.js site. Its CSS class names change on every deploy, which is what killed most earlier Kamernet bots. This server skips them and reads the structured __NEXT_DATA__ JSON embedded in each public page: the same data the site renders from, and stable across frontend redesigns.

Politeness is enforced in code: a transparent User-Agent linking to this repo, a minimum 1-second delay between requests, no robots.txt-disallowed endpoints, and no tricks to evade rate limits. PRs that weaken this are rejected.

Development

git clone https://github.com/jasp-nerd/kamernet-mcp
cd kamernet-mcp
uv sync --all-extras
uv run pytest          # 40+ tests, no network needed
uv run ruff check .

Tests run against sanitized snapshots of real Kamernet pages (tests/fixtures/) plus FastMCP's in-memory client, exercising the full MCP protocol without a browser or network. See CONTRIBUTING.md.

Debug interactively with the MCP Inspector:

npx @modelcontextprotocol/inspector uv run kamernet-mcp

Disclaimer

This is an unofficial, personal-use tool. It is not affiliated with, endorsed by, or connected to Kamernet B.V. in any way.

  • Intended for personal, non-commercial use (finding yourself a home). Scraping personal data at scale can violate the GDPR/AVG; the Dutch DPA (Autoriteit Persoonsgegevens) has published guidance on this. Don't harvest, republish or redistribute listing data.

  • You are responsible for complying with Kamernet's terms of service and applicable law.

  • Listing data can be wrong or stale. Verify on kamernet.nl before you decide anything, and never pay a deposit before viewing the room.

License

MIT © 2026 jasp-nerd

Available Tools

3 tools
get_listingA
Read-only

Get the full details of one Kamernet listing.

Includes the complete description in English and Dutch, rent and deposit, energy label, registration ('inschrijving') possibility, landlord statistics (member since, response rate, verification badges) and photo URLs.

ParametersJSON Schema
NameRequiredDescriptionDefault
listingYesFull listing URL (e.g. https://kamernet.nl/huren/utrecht/lange-jufferstraat/2393024) as returned by search_listings.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.2/5.0
Behavior4/5

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

Annotations declare readOnlyHint (safe read) and openWorldHint (unexpected fields possible). Description adds specific included fields (descriptions in both languages, rent, deposit, energy label, registration, landlord stats, photo URLs), providing clear behavioral context beyond annotations.

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: first states purpose, second lists what's included. No extraneous text, front-loaded with key action. Highly 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?

Given output schema exists (handles return values) and annotations provide safety info, description adequately covers tool function and output contents. Lacks error handling details but is sufficient for a simple read operation.

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 already fully covers the 'listing' parameter with format and source. Description adds no new semantic information beyond restating the parameter's purpose, so baseline 3 applies.

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?

Clear verb 'Get' and specific resource 'full details of one Kamernet listing'. Distinguishes from siblings: search_listings returns multiple, get_new_listings returns new listings.

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?

Specifies input format and origin (URL from search_listings). Lists included details. Implicit use case for single listing retrieval, but no explicit when-not or alternative guidance.

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

get_new_listingsA
Read-only

Check for listings that appeared since a given moment (stateless monitoring).

Sorts by newest and filters client-side on the availability publish window, so an agent can poll this periodically ("any new rooms since my last check?") without the server keeping state. Remember the timestamp you pass and advance it on each call. Do not poll more often than every few minutes — be polite.

ParametersJSON Schema
NameRequiredDescriptionDefault
cityYesDutch city name, e.g. 'Utrecht'.
sinceYesISO 8601 timestamp (e.g. '2026-07-16T09:00:00'). Only listings that became available on Kamernet after this moment are returned.
max_rentNo
min_sizeNo
radius_kmNoRadius in km.
listing_typesNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior5/5

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

Discloses sorting by newest, client-side filtering, statelessness, and politeness constraints. Annotations already indicate readOnly and openWorld, and description adds valuable behavioral context beyond those.

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?

Four sentences, all essential. First sentence states purpose, subsequent sentences add guidance and detail. No wasted words.

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?

Description covers the core use case well. Annotations confirm safety and open-world nature, and output schema exists. Minor gaps: no mention of optional filters like max_rent, but overall adequate.

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 coverage is 50% with descriptions for 3 of 6 parameters (city, since, radius_km). The description does not add further parameter details, so it meets a baseline but does not compensate for missing schema descriptions.

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 clearly states the tool checks for new listings since a given timestamp for stateless monitoring. It distinguishes from siblings (get_listing, search_listings) by focusing on incremental updates.

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

Usage Guidelines5/5

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

Explicitly advises polling periodically, remembering the timestamp, and not polling more than every few minutes. Provides clear usage context without needing to reference alternatives.

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

search_listingsA
Read-only

Search rental listings on Kamernet.nl (rooms, studios and apartments in the Netherlands).

Returns one page of listing summaries with price (euros/month), surface (m²), availability dates and a canonical URL per listing. Use get_listing with that URL for the full description, deposit, landlord stats and photos. Sponsored "top ads" are returned separately — they match the city but not necessarily the other filters.

ParametersJSON Schema
NameRequiredDescriptionDefault
cityYesDutch city name, e.g. 'Utrecht', 'Amsterdam', 'Den Haag'.
pageNoResult page, 18 listings per page.
sortNoSort order. 'newest' is best for finding fresh listings.newest
max_rentNoMaximum total rent in euros per month.
min_sizeNoMinimum surface area in m².
radius_kmNoSearch radius around the city in km (1, 2, 5, 10 or 20).
listing_typesNoFilter by property type. Omit for all types.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.5/5.0
Behavior4/5

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

Annotations already indicate readOnlyHint=true and openWorldHint=true. The description adds behavioral traits: returns one page of summaries, includes specific fields, and notes that sponsored ads may not match all filters. This exceeds what annotations provide without contradiction.

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 concise with four sentences, each adding essential information. It front-loads the purpose and resource, then details returns, directs to a sibling tool, and clarifies a special case. No superfluous content.

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?

Given the full schema coverage, annotations, and presence of an output schema, the description provides sufficient context. It explains core functionality, return fields, and a special behavior (sponsored ads), making the tool easy to use 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 coverage is 100% with descriptions for each parameter. The description adds meaning by stating that price is in euros/month and surface in m², and explains how sponsored ads behave, which aids in understanding the output beyond the raw 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 clearly states the verb 'search' and the resource 'rental listings on Kamernet.nl'. It specifies what is returned (price, surface, availability, URL) and distinguishes from the sibling tool get_listing by instructing to use it for full details.

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 explains that for full listing details one should use get_listing, and notes that sponsored top ads are returned separately. While it does not explicitly state when not to use this tool or mention get_new_listings, it provides useful context for selecting between tools.

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. 3 tool updatesv0.1.0
    • First observedget_listing
    • First observedget_new_listings
    • First observedsearch_listings

TDQS

A4.4/5.0

Scored across 3 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: search_listings for finding listings, get_listing for details of a specific listing, and get_new_listings for monitoring new listings. There is no overlap or ambiguity.

Naming Consistency5/5

All tools follow a consistent verb_noun pattern with camelCase (get_listing, get_new_listings, search_listings). The naming is predictable and easy to understand.

Tool Count5/5

With 3 tools, the server is well-scoped for its purpose of browsing and monitoring rental listings. Each tool is necessary and none are extraneous.

Completeness4/5

The tool set covers search, detail retrieval, and monitoring new listings, which are the core operations for a listing viewer. A minor gap is the lack of a separate tool for listing available cities or filter options, but search_listings likely handles filters adequately.

Maintenance

ActivitySlowing
ResponsivenessNo issues

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
    Not graded
    quality
    F
    maintenance
    Enables AI assistants to search and view advertisements on Marktplaats.nl with extensive filtering options.
    16
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    Enables AI agents to search and monitor Dutch and Belgian classifieds (Marktplaats and 2dehands) for listings, seller profiles, and categories.
    5
    2
    MIT