homeexchange-mcp
README.md
<div align="center">
# ๐ homeexchange-mcp
**An unofficial MCP server for [HomeExchange](https://www.homeexchange.com)**
Search homes ยท Read messages ยท Manage favourites ยท All from your AI client
[](https://github.com/osloer-industries/homeexchange-mcp/releases)
[](LICENSE)
[](https://sonarcloud.io/summary/new_code?id=osloer-industries_homeexchange-mcp)
[](https://github.com/osloer-industries/homeexchange-mcp#disclaimer)
> **Unofficial project.** Not affiliated with or endorsed by HomeExchange SAS.
> Personal use only โ see [disclaimer](#disclaimer).
</div>
---
## What you can do
Once connected, ask your AI client things like:
- *"Find homes in Lisbon for 2 guests in July, GuestPoints only"*
- *"Show me my unanswered messages"*
- *"Send a message to conversation 12345 asking about parking"*
- *"What homes have I favourited?"*
- *"Show the availability calendar for home 1950607"*
**20 tools across three categories:**
| Category | Tools |
|----------|-------|
| ๐ **Search & discovery** | `search_homes` ยท `get_home` ยท `get_home_calendar` ยท `get_recommendations` ยท `list_my_homes` ยท `list_favorites` ยท `add_favorite` ยท `remove_favorite` ยท `list_saved_searches` |
| ๐ฌ **Messaging** | `list_conversations` ยท `get_conversation` ยท `get_messages` ยท `get_exchange_request` ยท `send_message` ยท `start_conversation` ยท `pre_approve_exchange` ยท `archive_conversation` |
| ๐ค **Users** | `get_user_profile` ยท `get_user_ratings` ยท `get_user_achievements` |
---
## How it works
```
npm run login
โ
Browser opens โ you log in once
โ
session.json (token + cookies, stays local)
โ
npm run mcp
โ
MCP Server (local, stdio)
โ
โโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ โ โ
search & messaging users
discovery (8 tools) (3 tools)
(9 tools) โ โ
โ โโโโโโโโโโฌโโโโโโโโ
โโโโโโโโโโโโโโโโโโ
โ
api.homeexchange.com
bff.homeexchange.com
```
Auth is captured once via your real browser session โ no credentials stored in code. The MCP server runs locally and makes direct API calls on your behalf. Works with any MCP-compatible client.
---
## Quick start
### 1. Install
```bash
npm install
npx playwright install chromium
```
### 2. Capture your session
```bash
npm run login
```
A browser opens. Log in to HomeExchange, then press **Ctrl+C**. Your session is saved locally to `session.json` (git-ignored).
> Tokens expire after a few days. Re-run `npm run login` when tools start returning 401s.
### Optional location search configuration
Searching homes by a place name needs a personal geocoding token to resolve that name to a HomeExchange search location. Use `.env.example` as a reference, then export `HOMEEXCHANGE_GEOCODING_TOKEN` before starting the MCP server. Keep the token out of version control.
### 3. Start the MCP server
```bash
npm run mcp
```
## Local MCP testing
The project includes a local end-to-end smoke test. It builds the server,
starts it over stdio, performs the MCP handshake, and confirms that all tools
are available. It does not need a HomeExchange session and makes no network
requests.
```bash
npm run test:mcp
```
To run the built server in the same form used by the smoke test:
```bash
npm run mcp:local
```
After completing `npm run login`, you can also validate one read-only
HomeExchange call without displaying any account data:
```bash
npm run test:mcp -- --live
```
The live check calls `list_my_homes`. Do not use it for testing changes that
write data, and never commit `session.json` or `.env`.
---
## Client setup
Works with any MCP client that supports stdio transport.
### Claude Desktop
`~/Library/Application Support/Claude/claude_desktop_config.json`:
```json
{
"mcpServers": {
"homeexchange": {
"command": "npx",
"args": ["ts-node", "src/mcp.ts"],
"cwd": "/path/to/homeexchange-mcp"
}
}
}
```
### Claude Code
```bash
claude mcp add homeexchange -- npx ts-node src/mcp.ts
```
### Cursor
`~/.cursor/mcp.json`:
```json
{
"mcpServers": {
"homeexchange": {
"command": "npx",
"args": ["ts-node", "src/mcp.ts"],
"cwd": "/path/to/homeexchange-mcp"
}
}
}
```
### Zed
`.zed/settings.json`:
```json
{
"context_servers": {
"homeexchange": {
"command": { "path": "npx", "args": ["ts-node", "src/mcp.ts"] }
}
}
}
```
---
## Tool reference
### ๐ Search & discovery
#### `search_homes`
Search listings by location, dates, guests, and exchange type.
| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `location` | string | No | โ | City, region, or country |
| `checkin` | string | No | โ | `YYYY-MM-DD` |
| `checkout` | string | No | โ | `YYYY-MM-DD` |
| `guests` | number | No | โ | Number of guests |
| `exchange_type` | string | No | โ | `GuestPoints` ยท `simultaneous` ยท `non_simultaneous` |
| `home_type` | string | No | โ | `house` ยท `apartment` ยท `other` |
| `limit` | number | No | `20` | Results per page (max 36) |
| `offset` | number | No | `0` | Pagination offset |
#### `get_home`
Full details for a listing.
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `home_id` | string | **Yes** | Numeric home ID |
#### `get_home_calendar`
Availability calendar โ blocked and open dates for a home.
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `home_id` | string | **Yes** | Numeric home ID |
#### `get_recommendations`
Personalised picks based on your profile and history.
| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `limit` | number | No | `8` | Number of results |
#### `list_my_homes`
Your own listings. No parameters.
#### `list_favorites`
Your saved homes.
| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `limit` | number | No | `20` | Number of results |
#### `add_favorite`
Save a home to your favourites.
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `home_id` | string | **Yes** | Home ID |
#### `remove_favorite`
Remove a home from your favourites.
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `home_id` | string | **Yes** | Home ID |
#### `list_saved_searches`
Your saved search filters.
| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `limit` | number | No | `100` | Number of results |
---
### ๐ฌ Messaging
#### `list_conversations`
Your conversation inbox.
| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `filter` | string | No | `ALL` | `ALL` ยท `UNANSWERED` ยท `ARCHIVED` |
| `limit` | number | No | `20` | Threads to return |
| `after` | string | No | โ | Pagination cursor from previous response |
#### `get_conversation`
Extended information about a conversation, including exchange details.
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `conversation_id` | string | **Yes** | Conversation ID |
#### `get_messages`
All messages in a conversation thread.
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `conversation_id` | string | **Yes** | Conversation ID |
#### `get_exchange_request`
Exchange request details attached to a conversation.
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `conversation_id` | string | **Yes** | Conversation ID |
#### `send_message`
Reply in an existing conversation.
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `conversation_id` | string | **Yes** | Conversation ID |
| `text` | string | **Yes** | Message text |
#### `start_conversation`
Open a new conversation about a home.
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `home_id` | string | **Yes** | The home you're enquiring about |
| `text` | string | **Yes** | Opening message |
#### `pre_approve_exchange`
Pre-approve an exchange request.
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `conversation_id` | string | **Yes** | Conversation ID |
#### `archive_conversation`
Archive a conversation.
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `conversation_id` | string | **Yes** | Conversation ID |
---
### ๐ค Users
#### `get_user_profile`
A member's public profile.
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `user_id` | string | **Yes** | Numeric user ID |
#### `get_user_ratings`
Ratings left for a member.
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `user_id` | string | **Yes** | Numeric user ID |
#### `get_user_achievements`
Achievements earned by a member.
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `user_id` | string | **Yes** | Numeric user ID |
---
## Scripts
| Script | Description |
|--------|-------------|
| `npm run login` | Capture auth session via browser โ start here |
| `npm run mcp` | Start the local MCP server |
| `npm run record` | Full network recorder with HAR capture (API exploration) |
| `npm run analyze` | Analyze a `.har` file โ `api-map.json` |
| `npm run build` | Compile TypeScript |
| `npm run check` | Typecheck + lint + tests |
---
## Project layout
```
src/
login.ts browser auth capture
record.ts full network recorder with HAR output
analyze.ts HAR โ api-map.json analysis
api.ts authenticated HTTP client
mcp.ts MCP stdio server
tools/
search.ts 9 search & discovery tools
messaging.ts 8 messaging tools
user.ts 3 user tools
```
---
## Roadmap
Tracked as GitHub Issues โ upvote or comment to influence priority:
- [#9 Calendar integration](https://github.com/osloer-industries/homeexchange-mcp/issues/9) โ query and update availability, surface conflicts across requests
- [#10 Remote MCP](https://github.com/osloer-industries/homeexchange-mcp/issues/10) โ hosted endpoint, no local setup required
- [#11 Token expiry detection](https://github.com/osloer-industries/homeexchange-mcp/issues/11) โ auto-prompt on 401 *(good first issue)*
- [#12 Saved search alerts](https://github.com/osloer-industries/homeexchange-mcp/issues/12) โ notify when new homes match your saved searches
---
## Contributing
Ideas, bug reports, and pull requests are welcome.
**Got a feature idea or found a bug?** [Open an issue](https://github.com/osloer-industries/homeexchange-mcp/issues/new) โ describe what you were trying to do and what happened (or didn't).
**Want to contribute code?**
1. Fork the repo and create a branch from `main`
2. Make your changes โ keep commits [conventional](https://www.conventionalcommits.org/) (`fix:`, `feat:`, `chore:` etc.)
3. Open a pull request with a conventional title, such as `feat: add calendar filtering` or `fix(api): handle expired sessions`
4. Ensure all required checks pass before merge
**Good first issues** are tagged [`good first issue`](https://github.com/osloer-industries/homeexchange-mcp/labels/good%20first%20issue) โ start there if you're new to the codebase.
> Note: This project reverse-engineers a private API. New tools may break if HomeExchange changes their endpoints. Please check existing issues before reporting an API breakage.
---
## Releases
Release Please collects conventional commits on `main` into a release pull request. A maintainer reviews that pull request and merges it when the project is ready to publish. Merging it updates `CHANGELOG.md`, `package.json`, and `package-lock.json`, then creates the version tag and GitHub Release.
Before `1.0.0`, `feat:` and breaking changes increase the minor version, while `fix:`, `perf:`, and `revert:` increase the patch version. The release workflow consumes the organization Actions secret named `RELEASE_TOKEN` so its pull requests receive the normal required CI checks. Organization administrators must include this repository in the secret's selected-repository access policy. The underlying credential needs permission to write contents and pull requests, and an expiration that complies with organization policy.
Pull request titles are validated against the Conventional Commits format. Squash merges use the validated title as the commit subject so Release Please can calculate the correct version and changelog entry.
---
## Disclaimer
This is an **unofficial, community project** with no affiliation with HomeExchange SAS.
- Uses your own HomeExchange account credentials, exactly as your browser does
- **Personal, non-commercial use only** โ not for scraping, reselling, or commercial exploitation of HomeExchange data
- Subject to [HomeExchange's Terms of Service](https://www.homeexchange.com/en/page/terms)
- The HomeExchange API is private and undocumented โ endpoints may change without notice
**The intent is to build a genuinely useful tool for the HomeExchange community, and ideally to partner with HomeExchange to do this officially.** If you work at HomeExchange and are interested in collaborating on a proper integration, please [open an issue](https://github.com/osloer-industries/homeexchange-mcp/issues) or get in touch.
---
## License
[MIT](LICENSE) โ personal and non-commercial use.
*HomeExchangeยฎ is a registered trademark of HomeExchange SAS. This project is independent and not endorsed by HomeExchange SAS.*
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues