kamernet-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@kamernet-mcpFind a room in Amsterdam under €800 with registration."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
MCP server for Kamernet.nl: search Dutch rooms, studios and apartments from Claude, Cursor, Codex and any AI agent.
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.

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-mcpThen ask Claude to find you a room. For other clients, use an install badge or unfold yours below.
claude mcp add kamernet -- uvx kamernet-mcpOr 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-mcpOr 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-mcpThen use kamernet-mcp as the command in any of the configs above.
Related MCP server: marktplaats-mcp
Tools
Tool | What it does |
| Search by city with filters: max rent (€), min size (m²), radius (km), property type (room / apartment / studio / anti-squat / student housing), sort order, pagination. |
| Full details of one listing: bilingual description, rent + deposit, energy label, registration ("inschrijving") possibility, landlord stats (response rate, member since, verified badges), photos, coordinates. |
| Stateless monitoring: "what appeared since my last check?" Lets your agent poll without hammering the site. |
| Verify the configured Kamernet account can log in. |
| 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 |
| — | Enables authenticated tools. |
| — | Enables authenticated tools. |
|
| Minimum seconds between requests to kamernet.nl. Values below 1.0 are ignored. |
|
| Hard cap on automated replies per server session. |
| 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 chromiumSet KAMERNET_EMAIL and KAMERNET_PASSWORD in your MCP client's env block. Cookies are cached locally so login happens rarely.
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-mcpDisclaimer
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 toolsget_listingARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| listing | Yes | Full listing URL (e.g. https://kamernet.nl/huren/utrecht/lange-jufferstraat/2393024) as returned by search_listings. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_listingsARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| city | Yes | Dutch city name, e.g. 'Utrecht'. | |
| since | Yes | ISO 8601 timestamp (e.g. '2026-07-16T09:00:00'). Only listings that became available on Kamernet after this moment are returned. | |
| max_rent | No | ||
| min_size | No | ||
| radius_km | No | Radius in km. | |
| listing_types | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_listingsARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| city | Yes | Dutch city name, e.g. 'Utrecht', 'Amsterdam', 'Den Haag'. | |
| page | No | Result page, 18 listings per page. | |
| sort | No | Sort order. 'newest' is best for finding fresh listings. | newest |
| max_rent | No | Maximum total rent in euros per month. | |
| min_size | No | Minimum surface area in m². | |
| radius_km | No | Search radius around the city in km (1, 2, 5, 10 or 20). | |
| listing_types | No | Filter by property type. Omit for all types. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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.
3 tool updates
v0.1.0- First observed
get_listing - First observed
get_new_listings - First observed
search_listings
TDQS
Scored across 3 tools
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.
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.
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.
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
Related MCP Connectors
LinkedIn for AI agents: inbox, invitations, Sales Navigator search, posts. Quotas and webhooks.
Independent directory of agentic AI tools — search, compare & recommend via MCP. Read-only.
Vacation rental discovery, direct booking, and property protection for AI agents.
Travel tools for AI agents: plan and edit real trips, search stays and tours, import travel videos.
Related MCP Servers
- FlicenseBqualityNot gradedmaintenanceEnables 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.31-
- AlicenseNot gradedqualityFmaintenanceEnables AI assistants to search and view advertisements on Marktplaats.nl with extensive filtering options.16MIT
- FlicenseNot gradedqualityCmaintenanceEnables AI agents to search for German property listings (rent/buy) on immowelt.de with structured JSON output, no API key required.-
- AlicenseAqualityAmaintenanceEnables AI agents to search and monitor Dutch and Belgian classifieds (Marktplaats and 2dehands) for listings, seller profiles, and categories.52MIT