As of July 2026, Breezeway does not publish an official MCP server, so there is no one-click Claude connection yet. But Breezeway maintains a genuinely good public API, documented at developer.breezeway.io, that covers properties, reservations, tasks, people, templates, and webhooks. That means two routes work today: build a small read-only MCP server that wraps the API (about 25 minutes, working code below), or, for turnover photo review specifically, run the RapidEye Chrome extension on top of your existing Breezeway session with no code and no API keys at all.
Where Breezeway and Claude stand today
Breezeway is the operations layer for a large share of professional short-term rental programs: cleaning and inspection tasks, property status, scheduled turnovers, supplies, and the photo documentation that comes back from the field. If you run turnovers through it, Breezeway is where the operational truth lives, which is exactly why you want Claude to be able to see it.
The good news is that Breezeway treats its API as a first-class product. The developer hub at developer.breezeway.io splits into Guides and an API Reference with per-endpoint documentation and error codes, and, according to Breezeway's own getting-started guide, the platform even publishes an llms.txt index of every docs page in Markdown plus OpenAPI definitions, built specifically so AI agents can read the documentation. Very few PMS or operations platforms in this industry have done that. It is a strong signal about where Breezeway is headed on AI access.
What does not exist yet is a first-party MCP server, the piece that would let you paste a URL into Claude and be done. The demand is clearly there: in April 2026 an operator posted a $200 job on Upwork asking a freelancer to build an MCP connecting Claude to their PriceLabs and Breezeway accounts. You do not need to hire anyone. The build is small, and the code below is the whole thing.
A read-only MCP server on Breezeway's public API
A small Node.js server that exchanges your API credentials for a token and gives Claude four read-only tools: properties, tasks, task detail, and reservations.
- Full task data: status, assignments, times, costs, supplies
- Works in Claude Desktop and Claude Code
- Read-only by design, Claude cannot change anything
The RapidEye Chrome extension
For photo review specifically. It runs on your active Breezeway session in the browser, so there are no API keys and nothing to install beyond the extension.
- AI analysis of turnover task photos
- Flags damage, missing items, cleanliness issues
- No credentials, no setup, no code
What the Breezeway API exposes
Per the API Reference at developer.breezeway.io, the public API (base URL https://api.breezeway.io/public/inventory/v1) covers the core of a Breezeway operation:
Properties
List, retrieve, create, and update properties, plus property tags and contacts.
Tasks
List and retrieve tasks by property, filter by department (housekeeping, maintenance, inspection, safety), comments, tags, photos.
Reservations
Full lifecycle with check-in and check-out actions, and rich date filters on both ends of the stay.
People
List and retrieve the staff and service providers on your account.
Templates & supplies
Active task templates (checklists), subdepartments, and available supplies.
Webhooks
Subscribe to task events and property status changes for push-based workflows.
The task object is the deep one. Per Breezeway's Retrieve Task reference, a single task record carries assignments, status and stage, scheduled date, start and finish timestamps, total time, itemized costs with bill-to routing, supplies used with quantities and pricing, tags, a photos array, and a link to the shareable task report. That is a complete picture of a turnover, which is what makes this API worth connecting to Claude in the first place.
What you'll be able to ask Claude
Once the MCP server is registered, questions like these run against your live Breezeway data:
home_id or your external reference_property_id). Portfolio-wide questions still work: Claude lists your properties first, then loops the task query across them. It just means a 50-property sweep is 50 quick calls, not one.
Prerequisites
- An active Breezeway account with API credentials. Breezeway issues API keys on request via a form (step 1 below), not instant self-serve, so start that first.
- Claude Desktop or the Claude Code CLI. Download Claude Desktop.
- Node.js 18 or newer (20+ recommended). Check with
node --version.
Build the MCP server
Request your Breezeway API credentials
According to Breezeway's Obtaining Credentials guide, there are two paths:
- Account holders: with an active Breezeway account, complete the credential request form linked from the Obtaining Credentials page. You'll receive a
client_idandclient_secretscoped to your own account. - Integration partners: companies building for many Breezeway customers go through the Partnerships team and can receive cross-company credentials, a single key pair that reaches multiple linked accounts.
You want the first path. The review step is a feature, not friction: Breezeway knowing who is on its API is part of why the platform is trusted with operational data. Plan for the turnaround rather than around it.
Scaffold the project
mkdir breezeway-mcp && cd breezeway-mcp
npm init -y
npm pkg set type="module"
npm install @modelcontextprotocol/sdk zod
Write the server
Breezeway's auth flow, per its Authentication guide: POST your client_id and client_secret as JSON to https://api.breezeway.io/public/auth/v1/, get back a JWT access token good for 24 hours, and send it on every call as Authorization: JWT <token>. The token endpoint is rate limited to 1 request per minute, which is why the code below mints one token and caches it in memory instead of re-authenticating per call.
Save this as index.js. Four read-only tools, GET requests only:
#!/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 AUTH_URL = "https://api.breezeway.io/public/auth/v1/";
const API_BASE = "https://api.breezeway.io/public/inventory/v1";
const CLIENT_ID = process.env.BREEZEWAY_CLIENT_ID;
const CLIENT_SECRET = process.env.BREEZEWAY_CLIENT_SECRET;
if (!CLIENT_ID || !CLIENT_SECRET) {
console.error("Set BREEZEWAY_CLIENT_ID and BREEZEWAY_CLIENT_SECRET first.");
process.exit(1);
}
// Access tokens last 24h and the auth endpoint is limited to
// 1 req/min, so mint once and cache in memory.
let token = null;
let tokenBornAt = 0;
async function getToken() {
const ageHours = (Date.now() - tokenBornAt) / 3600000;
if (token && ageHours < 23) return token;
const res = await fetch(AUTH_URL, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
client_id: CLIENT_ID,
client_secret: CLIENT_SECRET,
}),
});
if (!res.ok) throw new Error(`Breezeway auth failed (${res.status})`);
token = (await res.json()).access_token;
tokenBornAt = Date.now();
return token;
}
async function get(path, params = {}) {
const url = new URL(`${API_BASE}${path}`);
for (const [k, v] of Object.entries(params)) {
if (v !== undefined && v !== null && v !== "") {
url.searchParams.append(k, String(v));
}
}
const res = await fetch(url, {
headers: { Authorization: `JWT ${await getToken()}` },
});
if (!res.ok) throw new Error(`Breezeway ${res.status}: ${await res.text()}`);
return res.json();
}
function json(data) {
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
}
const server = new McpServer({ name: "breezeway", version: "1.0.0" });
server.registerTool(
"list_properties",
{
description:
"List properties in the Breezeway account. Returns Breezeway home ids needed by list_tasks. Use this first.",
inputSchema: {
limit: z.number().optional().describe("Max rows per page, default 100"),
page: z.number().optional().describe("Page number, default 1"),
},
},
async ({ limit, page }) => json(await get("/property", { limit, page }))
);
server.registerTool(
"list_tasks",
{
description:
"List tasks for ONE property (Breezeway requires a property id per call). Filter by department or scheduled date. Loop over properties for portfolio-wide questions.",
inputSchema: {
home_id: z.number().describe("Breezeway property id (from list_properties)"),
type_department: z
.enum(["maintenance", "housekeeping", "inspection", "safety"])
.optional()
.describe("Filter to one department"),
scheduled_date: z
.string()
.optional()
.describe("Scheduled date filter, YYYY-MM-DD"),
limit: z.number().optional().describe("Max rows per page, default 100"),
page: z.number().optional().describe("Page number, default 1"),
},
},
async ({ home_id, type_department, scheduled_date, limit, page }) =>
json(
await get("/task/", { home_id, type_department, scheduled_date, limit, page })
)
);
server.registerTool(
"get_task",
{
description:
"Retrieve one task in full: assignments, status, times, total_time, costs, supplies, tags, photos, and the task report URL.",
inputSchema: { task_id: z.number().describe("Breezeway task id") },
},
async ({ task_id }) => json(await get(`/task/${task_id}`))
);
server.registerTool(
"list_reservations",
{
description:
"List reservations, optionally for one property or within a check-in date window.",
inputSchema: {
property_id: z.number().optional().describe("Breezeway property id"),
checkin_date_ge: z.string().optional().describe("Check-in on/after, YYYY-MM-DD"),
checkin_date_le: z.string().optional().describe("Check-in on/before, YYYY-MM-DD"),
limit: z.number().optional().describe("Max rows per page, default 100"),
page: z.number().optional().describe("Page number, default 1"),
},
},
async ({ property_id, checkin_date_ge, checkin_date_le, limit, page }) =>
json(
await get("/reservation", {
property_id,
checkin_date_ge,
checkin_date_le,
limit,
page,
})
)
);
const transport = new StdioServerTransport();
await server.connect(transport);
Register it with Claude
Claude Desktop: edit the config file and merge this into your mcpServers block:
{
"mcpServers": {
"breezeway": {
"command": "node",
"args": ["/absolute/path/to/breezeway-mcp/index.js"],
"env": {
"BREEZEWAY_CLIENT_ID": "your_client_id",
"BREEZEWAY_CLIENT_SECRET": "your_client_secret"
}
}
}
}
Then fully quit and reopen Claude Desktop (Cmd+Q on macOS; closing the window is not enough).
Claude Code: one command instead:
claude mcp add breezeway \
--env BREEZEWAY_CLIENT_ID=your_client_id \
--env BREEZEWAY_CLIENT_SECRET=your_client_secret \
-- node /absolute/path/to/breezeway-mcp/index.js
First prompt to try: "List my Breezeway properties, then show today's housekeeping tasks at the first one with status and assignee."
The zero-code route: AI on your Breezeway photos
The API route above is the right tool for questions about tasks, costs, schedules, and reservations. But the highest-value data in a turnover is often the photos your cleaners attach to tasks, and reviewing those with a general chat setup means a lot of manual downloading and uploading.
RapidEye Inspections for Chrome
Our Chrome extension puts an analyze button directly inside Breezeway. Open Breezeway, click Analyze latest 5 tasks, and it reviews the photos on your recently completed cleaning tasks with AI trained on vacation rentals, flagging property damage, missing items, and cleanliness issues. It works over your own active Breezeway session: no passwords, no API keys, no setup.
If you'd rather build photo analysis into your own pipeline, RapidEye also has an API, and a native Breezeway sync inside the RapidEye app.
Troubleshooting and FAQ
Does Breezeway have an official MCP server?
Not as of July 2026. No first-party MCP server appears in Breezeway's developer documentation or in the public MCP directories we checked. Given that Breezeway already publishes an llms.txt index and OpenAPI definitions for AI agents, the groundwork is visibly there; if Breezeway ships one, prefer it over a homemade server and we will update this guide.
I get 429 Too Many Requests when authenticating
Per Breezeway's Authentication guide, the token endpoints are rate limited to 1 request per minute, and the 429 response includes expiry information in the header and body. This usually means your code is re-authenticating on every call. The server above caches the token in memory for 23 hours; if you restarted it several times in a row while testing, wait a minute and try again.
401 Unauthorized on API calls
Check the header format first: Breezeway expects Authorization: JWT <token>, with the literal prefix JWT, not Bearer. Access tokens expire after 24 hours; the server handles that by minting a fresh one, but if you hand-rolled changes, confirm the token is under 24 hours old. Refresh tokens last 30 days, and each refresh call at /public/auth/v1/refresh returns a new refresh token.
list_tasks errors asking for home_id
By design: Breezeway's List Tasks endpoint retrieves tasks for a specified property, so every call needs either a Breezeway home_id or your external reference_property_id. Run list_properties first to get ids, or just ask Claude the question naturally and it will chain the two calls itself.
Claude doesn't see any Breezeway tools
Claude Desktop reads the config only at startup. Fully quit (Cmd+Q on macOS, quit from the tray on Windows) and reopen. Still nothing: check for invalid JSON in the config, a wrong absolute path to index.js, or node missing from PATH. Claude Desktop's logs folder (Help menu) shows the startup error.
Can Claude create or close tasks through this?
Not with this server: it only issues GET requests, on purpose. Breezeway's API does support writes (create task, update task, close task, add task photo, and more), so you can add them by registering additional tools that POST or PUT. We'd keep any write server separate from the read server, so exploratory questions can never accidentally modify a live turnover board.
I manage multiple Breezeway companies
Breezeway supports cross-company access: partners can use a single set of API keys to reach multiple linked companies, and the API includes a List Companies endpoint that returns the active companies your token can access. Task and property calls then accept a company reference. See the Cross-Company Access guide at developer.breezeway.io for the mechanics.
Sources
- Getting Started with Breezeway's API, Breezeway Developer Hubhttps://developer.breezeway.io/docs/getting-started
- Obtaining Credentials, Breezeway Developer Hubhttps://developer.breezeway.io/docs/obtaining-credentials
- Authentication, Breezeway Developer Hubhttps://developer.breezeway.io/docs/authentication
- List tasks, Breezeway API Referencehttps://developer.breezeway.io/reference/list-tasks
- Retrieve task, Breezeway API Referencehttps://developer.breezeway.io/reference/retrieve-task
- Breezeway Documentation llms.txt indexhttps://developer.breezeway.io/llms.txt
- Create MCP to connect my claude AI with pricelabs and breezeway, Upwork job posting (April 2026)https://www.upwork.com/freelance-jobs/apply/Create-MCP-connect-claude-with-pricelabs-and-breezeway_~022049352387174466940/
- RapidEye Inspections, Chrome Web Storehttps://chromewebstore.google.com/detail/rapideye-inspections/lpelonobdodfaapaejodmgacpgigfkoc
- Model Context Protocol TypeScript SDKhttps://github.com/modelcontextprotocol/typescript-sdk
Other guides in this series
The pattern is the same across the stack: credentials in, read-only tools out. Browse all of them at Claude Guides.

