Confused? Book a call with Sam
MCP Guide

Connect Hostfully to Claude

Run a small local server so Claude can read your Hostfully properties, bookings, orders, and guests, and answer questions about them in plain English. Free, working code, about fifteen minutes.

~15 minutes Read-only by default Updated June 2026
Hand it to Claude Code

To connect Hostfully to Claude, you run a small MCP server: a lightweight program on your own machine that wraps the Hostfully Platform API and exposes it to Claude as a set of tools. Once it's connected, Claude can read your properties, bookings, orders, and guests and answer questions about them, with no dashboards or exports.

MCP (the Model Context Protocol) is an open standard from Anthropic that lets AI assistants talk to outside systems. There is no official Hostfully MCP server as of June 2026, so this guide builds a focused, read-only one. Hostfully's API uses a single self-serve key you paste into a header, so there is no OAuth token dance to deal with.

What you can ask once it's connected

Before you start

Three things: a Hostfully account on a plan that includes API access (so an API key appears on your Agency Settings page), Node.js 18 or newer (20+ recommended; check with node --version), and either Claude Desktop or Claude Code.

1

Get your API key and agency UID

Sign in at platform.hostfully.com and open Agency Settings. You need two values from this page: your API key (in the API access section) and your agency UID (near the bottom of the page). The agency UID is how the API knows which agency's properties and bookings to return.

Treat the API key like a password. It grants access to your whole agency. According to Hostfully's API documentation, the key is sent in every request as the X-HOSTFULLY-APIKEY header. If your plan does not show an API key, API access is a plan-level feature, contact Hostfully to enable it.
2

Scaffold the project

Make a folder and install the two dependencies, the official MCP SDK and zod (used to describe each tool's inputs). No build step, no TypeScript compiler.

terminal
mkdir hostfully-mcp && cd hostfully-mcp
npm init -y
npm pkg set type="module"
npm install @modelcontextprotocol/sdk zod
3

Write the server

Save this as index.js. Because Hostfully authenticates with a header, there is no token step: every request just carries your API key. The file reads your key and agency UID from the environment and exposes six read-only tools. That's the whole thing.

index.js
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

const API_BASE = "https://api.hostfully.com/api/v3.3";
const API_KEY = process.env.HOSTFULLY_API_KEY;
const AGENCY_UID = process.env.HOSTFULLY_AGENCY_UID;

if (!API_KEY || !AGENCY_UID) {
  console.error("Set HOSTFULLY_API_KEY and HOSTFULLY_AGENCY_UID first.");
  process.exit(1);
}

// Authenticated GET. The API key rides in a header on every request.
async function get(path) {
  const res = await fetch(`${API_BASE}${path}`, {
    headers: { "X-HOSTFULLY-APIKEY": API_KEY, Accept: "application/json" },
  });
  if (!res.ok) throw new Error(`Hostfully ${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: "hostfully", version: "1.0.0" });

server.registerTool(
  "list_properties",
  {
    description: "List the properties in the Hostfully agency.",
    inputSchema: {
      limit: z.number().optional().describe("Max rows per page, 1-100, default 100"),
      cursor: z.string().optional().describe("nextCursor from a previous page"),
    },
  },
  async ({ limit, cursor }) => {
    const q = new URLSearchParams({ agencyUid: AGENCY_UID, _limit: String(limit ?? 100) });
    if (cursor) q.set("_cursor", cursor);
    return json(await get(`/properties?${q}`));
  }
);

server.registerTool(
  "get_property",
  {
    description: "Get full details for one property by its UID.",
    inputSchema: { propertyUid: z.string().describe("Hostfully property UID") },
  },
  async ({ propertyUid }) => json(await get(`/properties/${propertyUid}`))
);

server.registerTool(
  "list_leads",
  {
    description: "List bookings (Hostfully calls them leads), optionally filtered by property or check-in date range.",
    inputSchema: {
      propertyUid: z.string().optional().describe("Limit to one property"),
      checkInFrom: z.string().optional().describe("Earliest check-in, YYYY-MM-DD"),
      checkInTo: z.string().optional().describe("Latest check-in, YYYY-MM-DD"),
      limit: z.number().optional().describe("Max rows per page, 1-100, default 100"),
      cursor: z.string().optional().describe("nextCursor from a previous page"),
    },
  },
  async ({ propertyUid, checkInFrom, checkInTo, limit, cursor }) => {
    const q = new URLSearchParams({ _limit: String(limit ?? 100) });
    if (propertyUid) q.set("propertyUid", propertyUid);
    else q.set("agencyUid", AGENCY_UID);
    if (checkInFrom) q.set("checkInFrom", checkInFrom);
    if (checkInTo) q.set("checkInTo", checkInTo);
    if (cursor) q.set("_cursor", cursor);
    return json(await get(`/leads?${q}`));
  }
);

server.registerTool(
  "get_lead",
  {
    description: "Get one booking (lead) by its UID, including check-in, check-out, and guest.",
    inputSchema: { leadUid: z.string().describe("Hostfully lead UID") },
  },
  async ({ leadUid }) => json(await get(`/leads/${leadUid}`))
);

server.registerTool(
  "list_orders",
  {
    description: "List financial orders for one property (get the propertyUid from list_properties first).",
    inputSchema: { propertyUid: z.string().describe("Hostfully property UID") },
  },
  async ({ propertyUid }) => {
    const q = new URLSearchParams({ propertyUid });
    return json(await get(`/orders?${q}`));
  }
);

server.registerTool(
  "list_guests",
  {
    description: "List all guests in the agency.",
    inputSchema: {},
  },
  async () => json(await get(`/guests/${AGENCY_UID}`))
);

const transport = new StdioServerTransport();
await server.connect(transport);
console.error("Hostfully MCP server running on stdio");
Large portfolio? Hostfully pages results with _limit (max 100) and _cursor, and returns a nextCursor inside each response's extensions block. If you run 100+ units and ask Claude to total a full month, tell it to page through with the cursor or narrow by property and date, otherwise it sees only the first 100 rows.
4

Connect it to Claude

Point Claude at the server and pass your two values.

Claude Desktop

Add a hostfully entry to your config file (~/Library/Application Support/Claude/claude_desktop_config.json on macOS, %AppData%\Claude\claude_desktop_config.json on Windows), then fully quit and reopen the app.

claude_desktop_config.json
{
  "mcpServers": {
    "hostfully": {
      "command": "node",
      "args": ["/ABSOLUTE/PATH/TO/hostfully-mcp/index.js"],
      "env": {
        "HOSTFULLY_API_KEY": "your-api-key",
        "HOSTFULLY_AGENCY_UID": "your-agency-uid"
      }
    }
  }
}
Claude Code

One command from your terminal. Everything after -- is what launches the server.

terminal
claude mcp add \
  --env HOSTFULLY_API_KEY=your-api-key \
  --env HOSTFULLY_AGENCY_UID=your-agency-uid \
  --transport stdio hostfully \
  -- node /ABSOLUTE/PATH/TO/hostfully-mcp/index.js

Confirm with claude mcp list. Add --scope user to make it available in every project.

5

Ask away

Start a new conversation. Claude asks permission the first time it calls a tool, approve it, and you're set.

try these
Which bookings check in over the next 7 days? Group them by property.

How many properties do we manage, and which look inactive?

Pull the orders for the lake house and total the revenue this month.

Prefer to skip the typing?

Paste this into Claude Code (or any coding agent) and it will build, install, and wire up the server for you. Then come back to step 1 for your key and agency UID.

prompt for Claude Code
Build a local MCP server (Node.js, ESM, @modelcontextprotocol/sdk and zod)
that wraps the Hostfully Platform API v3.3 (base https://api.hostfully.com/api/v3.3).
Read HOSTFULLY_API_KEY and HOSTFULLY_AGENCY_UID from the environment. Send the
key on every request as the X-HOSTFULLY-APIKEY header (no OAuth). Add an
authenticated GET helper that returns the parsed JSON body. Register these
read-only tools, built with URLSearchParams, default _limit 100, with optional
_cursor for pagination: list_properties(limit?, cursor?) -> /properties?agencyUid,
get_property(propertyUid) -> /properties/{uid}, list_leads(propertyUid?,
checkInFrom?, checkInTo?, limit?, cursor?) -> /leads (send agencyUid when no
propertyUid), get_lead(leadUid) -> /leads/{uid}, list_orders(propertyUid) ->
/orders?propertyUid, list_guests() -> /guests/{agencyUid}. Use
StdioServerTransport; log startup to stderr. Then make a package.json
(type: module), install the deps, and show me the claude mcp add command,
the claude_desktop_config.json block, and three prompts to try.

Good to know

One Hostfully connection worth its own server: your turnover photos. This MCP server gives you conversational access to bookings and properties. RapidEye covers the other half of the operation, the turnover itself, reading the inspection photos your cleaners capture after each clean and flagging damage and missed cleaning before the next guest checks in.

FAQ

Does Hostfully have an official MCP server?

Not as of June 2026. Hostfully publishes a Platform API but no first-party MCP server, and there is no widely used community one either. Build a focused one yourself (this guide). API keys are self-serve on Agency Settings for plans that include API access.

What is a "lead" in Hostfully?

A booking or inquiry, the reservation itself, not a sales prospect. The /leads endpoint is where arrivals, dates, and guests live; /orders is the financial record tied to a booking.

Is it safe to connect my real account?

The server here is read-only, so Claude can look but not touch. Your API key stays on your machine and Claude asks before every tool call.

Can I do this with Hostaway, Guesty, or OwnerRez too?

Yes. The structure is identical for any PMS with a public REST API; only the auth step changes. See our Hostaway, OwnerRez, and Hospitable guides for worked examples.

Sources

Independent integration guide. RapidEye is not affiliated with or endorsed by Hostfully or Anthropic. API behavior and dashboard menus can change; confirm specifics against the official docs above. Last reviewed June 14, 2026.