Connect Hospitable to Claude
Ask Claude about your Hospitable properties, reservations, and calendar availability in plain English. Bearer token auth, 10-minute setup, open-source MCP server.
Cole Rubin at Conduit shipped Claude MCP guides for 8 PMSes. Hospitable (formerly Smartbnb), one of the fastest-growing US vacation rental platforms, was missing from his list. This guide fills that gap using the same 4-step format and the same @modelcontextprotocol/sdk pattern.
What you'll be able to ask Claude
Once connected, Claude can pull live data from your Hospitable account. Example queries:
Prerequisites
- Hospitable account on Host, Professional, or Mogul plan. The public API is not available on the Essentials plan. Check your plan in Hospitable Settings → Billing.
- Claude Desktop installed, or the Claude Code CLI. Download Claude Desktop.
- Node.js 18 or later. Check with
node --version.
Generate a Hospitable Personal Access Token
Hospitable uses OAuth2 Bearer tokens. You'll generate a Personal Access Token (PAT) from the account settings. Only account owners can create PATs.
- Log in to my.hospitable.com.
- Click Apps in the sidebar (or Settings → Integrations, depending on your view).
- Open the Access tokens tab.
- Click + Add new.
- Give the token a name (e.g. "Claude MCP") and choose read permissions for this guide. You can give it write permissions too if you plan to extend the server to create/update reservations.
- Copy the token. Hospitable shows it only once. It looks like a long random string.
Note: Hospitable Personal Access Tokens expire after one year. Mark your calendar to rotate it before then. If you're building a multi-customer integration (not this guide), use OAuth2 instead of PATs.
Set up the Node.js project
Two dependencies: the MCP SDK and zod. Hospitable doesn't have an official Node SDK, so we'll make HTTP calls directly.
mkdir hospitable-mcp
cd hospitable-mcp
npm init -y
npm install @modelcontextprotocol/sdk zod
Add "type": "module" to package.json:
{
"name": "hospitable-mcp",
"version": "1.0.0",
"type": "module",
"main": "index.js",
"dependencies": {
"@modelcontextprotocol/sdk": "^1.0.0",
"zod": "^3.22.0"
}
}
Create the MCP server file
Save the following as index.js. The server exposes four tools: list-properties, list-reservations, get-reservation, and get-property-calendar.
#!/usr/bin/env node
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
const TOKEN = process.env.HOSPITABLE_TOKEN;
const BASE_URL = "https://public.api.hospitable.com/v2";
if (!TOKEN) {
console.error("Missing HOSPITABLE_TOKEN environment variable");
process.exit(1);
}
async function hospitableGet(path, params = {}) {
const url = new URL(`${BASE_URL}${path}`);
for (const [key, value] of Object.entries(params)) {
if (value !== undefined && value !== null && value !== "") {
url.searchParams.append(key, String(value));
}
}
const response = await fetch(url.toString(), {
method: "GET",
headers: {
Authorization: `Bearer ${TOKEN}`,
Accept: "application/json",
"User-Agent": "rapideye-hospitable-mcp/1.0",
},
});
if (!response.ok) {
const body = await response.text();
throw new Error(`Hospitable API ${response.status}: ${body}`);
}
return response.json();
}
const server = new McpServer({
name: "hospitable",
version: "1.0.0",
});
// Tool 1: List properties
server.tool(
"list-properties",
"List all properties on the Hospitable account. Returns property ID, name, address, bedroom/bathroom count, and status. Use this first to discover property IDs.",
{
page: z
.number()
.optional()
.describe("Page number for pagination (default: 1)"),
per_page: z
.number()
.optional()
.describe("Results per page (default: 25, max: 100)"),
},
async ({ page, per_page }) => {
const data = await hospitableGet("/properties", { page, per_page });
return {
content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
};
}
);
// Tool 2: List reservations with date filter and property include
server.tool(
"list-reservations",
"List reservations, optionally filtered by date range or property. Use include='property' to also return the associated property details in the response.",
{
start_date: z
.string()
.optional()
.describe("Filter reservations with check-in on or after this date (YYYY-MM-DD)"),
end_date: z
.string()
.optional()
.describe("Filter reservations with check-in on or before this date (YYYY-MM-DD)"),
property_id: z
.string()
.optional()
.describe("Only return reservations for this property ID"),
include: z
.string()
.optional()
.describe("Comma-separated list of related resources to include (e.g. 'property,guest')"),
page: z.number().optional(),
per_page: z.number().optional(),
},
async ({ start_date, end_date, property_id, include, page, per_page }) => {
const data = await hospitableGet("/reservations", {
start_date,
end_date,
property_id,
include,
page,
per_page,
});
return {
content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
};
}
);
// Tool 3: Fetch one reservation
server.tool(
"get-reservation",
"Fetch a single reservation by ID. Returns full details including guest info, dates, nightly rate, and any notes.",
{
id: z.string().describe("Reservation ID"),
include: z
.string()
.optional()
.describe("Optional related resources to include (e.g. 'property,guest')"),
},
async ({ id, include }) => {
const data = await hospitableGet(`/reservations/${id}`, { include });
return {
content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
};
}
);
// Tool 4: Property calendar
server.tool(
"get-property-calendar",
"Fetch the calendar (availability, pricing, min stay) for a specific property across a date range.",
{
property_id: z.string().describe("Hospitable property ID"),
start_date: z.string().describe("Start date (YYYY-MM-DD)"),
end_date: z.string().describe("End date (YYYY-MM-DD)"),
},
async ({ property_id, start_date, end_date }) => {
const data = await hospitableGet(`/properties/${property_id}/calendar`, {
start_date,
end_date,
});
return {
content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
};
}
);
const transport = new StdioServerTransport();
await server.connect(transport);
To extend the server, copy the server.tool(...) pattern and point at any endpoint in the Hospitable v2 reference.
Register the server with Claude Desktop
Open your Claude Desktop config file:
~/Library/Application Support/Claude/claude_desktop_config.json
%APPDATA%\Claude\claude_desktop_config.json
Add the Hospitable entry:
{
"mcpServers": {
"hospitable": {
"command": "node",
"args": ["/absolute/path/to/hospitable-mcp/index.js"],
"env": {
"HOSPITABLE_TOKEN": "your_personal_access_token_here"
}
}
}
}
Replace the path and token with your real values. Then fully quit and reopen Claude Desktop.
Try your first query
Start with a simple read to confirm the connection:
Then try a harder query: "What reservations do I have checking in between April 15 and April 30? Include the property name for each." Claude will call list-reservations with include=property and format the result for you.
Troubleshooting
401 Unauthorized on every call
Your Personal Access Token is wrong, expired, or your account plan was downgraded to Essentials (which loses API access). Regenerate the token in my.hospitable.com → Apps → Access tokens.
Hospitable PATs expire after one year. If it's been about that long since you made it, rotate the token.
403 Forbidden on /v2/properties
Your Hospitable plan likely doesn't include public API access. The Essentials plan is excluded — you'll need to be on Host, Professional, or Mogul. Check your plan in Hospitable Settings → Billing.
Claude doesn't see any Hospitable tools
Claude Desktop only reads the config file at startup. Fully quit Claude (Cmd+Q on macOS, right-click tray icon → Quit on Windows) and reopen it. Closing the window is not enough.
Still broken? Check the logs: Help → Open Logs Folder. Look for JSON parse errors in the config or path-not-found errors for index.js.
"include=property" returns reservations without property data
Known quirk reported in the Hospitable community: the include parameter sometimes doesn't return the expected related resources on older v2 endpoints. If you hit this, make a second call with get-property-calendar or fetch the property directly with list-properties and filter client-side.
I want to post messages or modify reservations
The Hospitable API supports write operations including creating/updating reservations and sending messages. Generate your PAT with write permissions, then add a tool that uses fetch with method: "POST" or "PATCH" and a JSON body. Consult developer.hospitable.com for the exact schemas.
What's next
Guide 3 of the batch 1 series. If you run on OwnerRez instead of Hospitable, start with that guide. If you have smart locks, the Seam guide wraps 8+ lock brands with a single MCP connector.