Direct answer

You can connect Oracle OPERA Cloud to Claude today, but not with a toggle. Oracle exposes OPERA Cloud through the Oracle Hospitality Integration Platform, OHIP, a catalog of more than 3,100 REST operations covering reservations, housekeeping, profiles, and front office. There is no official Oracle MCP server for hospitality as of July 2026, so the bridge is a small Model Context Protocol server you run yourself, authenticated with OAuth 2.0 client credentials and an application key. The code is an afternoon. The access is the real project: OHIP registration, environment credentials, and property-level authorization from the hotel. This guide covers both honestly.

The enterprise reality, upfront

OPERA Cloud is the PMS that large and chain hotels actually run, and its API surface is bigger and more open than its reputation suggests. But it is priced and gated like the enterprise system it is. According to Oracle's OHIP datasheet (2025), a hotel's access to OHIP is included in OPERA Cloud Property Management Foundation, while the party consuming the APIs is billed monthly in arrears, starting at $10 for up to 10,000 REST API transactions per month. Oracle has also published the full REST API specifications as an open-source project on GitHub, with Postman collections containing over 1,000 sample messages, so you can read every endpoint before you spend a dollar.

$10 / 10k calls

OHIP REST API pricing starts at $10 for up to 10,000 transactions per month, billed in arrears with no upfront commitment, per Oracle's OHIP datasheet. A Claude session asking a few dozen questions a day rounds to pocket change.

3,100+ operations

Oracle counts over 3,100 available operations in the OHIP catalog: reservations, housekeeping, CRM profiles, front office, inventory, cashiering, and more.

The hotel holds the keys

Per Oracle, hotels decide exactly who has access to what APIs in their environment. No property authorization, no data, no matter how good your code is.

What you'll be able to ask Claude

These map directly to the tools in the server below, which sit on OPERA Cloud's Housekeeping and Reservation APIs.

"Give me the housekeeping overview for the property: how many rooms are dirty, clean, and inspected right now?"
"List every room where the housekeeping status disagrees with the front office status, and flag the due-outs."
"Compare today's arrivals against rooms that are already inspected. Which arrivals have no room ready?"
"Which rooms are out of order, with what reason codes, and how long have they been out?"
"Pull reservations arriving in the next 7 days and group them by room type so I can plan deep cleans."

One caveat worth naming: OPERA's room status is a code someone set, not evidence. A room can read Inspected while the shower drain is clogged. Status tells you a human signed off; it cannot tell you what the room looks like. That gap between recorded status and physical condition is the problem RapidEye exists for: it reads the actual room photos and flags damage and cleaning misses that status codes never carry.

The architecture, layer by layer

Four layers. You own the middle two; Oracle and Anthropic own the ends. Nothing in this chain stores OPERA data at rest, and the OPERA credentials never touch Claude itself, only your local MCP server process.

Claude DesktopAnthropic
Discovers your server's tools over the Model Context Protocol and decides when to call them. Sees only the JSON responses, never the credentials.
stdio, local process
MCP serverYou, ~150 lines of Node
Holds the OHIP credentials, mints and caches the OAuth token, and exposes four read-only tools. The full file is in step 3.
HTTPS + OAuth 2.0 bearer token
OHIP API gatewayOracle Hospitality Integration Platform
Validates the token, your x-app-key, and your application's API subscriptions, then routes the call. Tokens come from POST /oauth/v1/tokens on the same gateway.
Property-authorized access only
OPERA Cloud propertyThe hotel's live environment
Identified per-request by the x-hotelid header. The hotel assigns which APIs your application may reach in its environment.

Prerequisites: the five values you need

Two routes into OHIP. If you work at a hotel running OPERA Cloud, your property already has OHIP entitlement through OPERA Cloud Foundation; work with whoever administers your Oracle environment. If you are an outside vendor, Oracle's onboarding docs describe self-registering through the Oracle Store or submitting a partner registration form via hospitality-integrations_ww@oracle.com. Either way, before writing any code, you need five values out of the OHIP developer portal and your hotel:

ValueWhere it comes fromUsed as
OHIP_CLIENT_ID / OHIP_CLIENT_SECRETOAuth client credentials for the environment, obtained through the OHIP developer portalBasic auth header on the token request
OHIP_APP_KEYIssued when you register an application in the developer portalx-app-key header on every call
OHIP_HOTEL_IDThe property code for the OPERA Cloud environment you are targetingx-hotelid header and URL path
OHIP_GATEWAY_URLThe environment's gateway URL, shown when the environment is added in the portalBase URL for tokens and all API calls
OHIP_SCOPEAssigned scope for your integration, required with the client_credentials grantBody parameter on the token request

Plus the usual pair: Claude Desktop (download) or the Claude Code CLI, and Node.js 18+ (node --version to check). Oracle also runs a non-production OPERA Cloud sandbox that is API-only and charged per call, which the OHIP datasheet positions as a cheap alternative to maintaining your own lab. Build against sandbox first.

01

Get OHIP access and collect your credentials

This is the step that takes calendar time, so start it first. Oracle's own documentation describes the flow for partners: choose an onboarding route (Oracle Store checkout or the partner registration form), activate the Oracle Cloud account when the activation email arrives, then use the OHIP developer portal to register an application, get an application key, subscribe the application to the APIs you need, and obtain credentials for the OPERA Cloud environment you are connecting to.

  • Hotel-side reader: your property's OHIP entitlement is already part of OPERA Cloud Foundation. You need whoever owns your Oracle environment to add you to the developer portal and provision environment credentials.
  • Vendor-side reader: self-registration gets you portal access, but a live hotel still has to authorize your application's API access in its environment. Per Oracle, the hotel remains in control by assigning the appropriate API access. Budget for that conversation.
  • For this guide, subscribe your application to at least the Housekeeping (hsk) and Reservation (rsv) APIs.

While you wait, read the API specs. Oracle publishes them all in the open-source oracle/hospitality-api-docs repo (Universal Permissive License), including the exact Swagger files this guide's endpoints were verified against.

02

Set up the Node.js project

Two dependencies: the MCP SDK and zod. OHIP is plain REST, so raw fetch is all we need.

Terminal
mkdir opera-mcp
cd opera-mcp
npm init -y
npm install @modelcontextprotocol/sdk zod

Add "type": "module" to package.json:

package.json
{
  "name": "opera-mcp",
  "version": "1.0.0",
  "type": "module",
  "main": "index.js",
  "dependencies": {
    "@modelcontextprotocol/sdk": "^1.0.0",
    "zod": "^3.22.0"
  }
}
03

Create the MCP server file

Save the following as index.js. It mints an OAuth token with the client_credentials grant (Basic auth of ClientID:ClientSecret plus x-app-key, exactly as Oracle's OAuth API spec describes), caches it until shortly before expiry, and exposes four read-only tools against endpoints from Oracle's published Swagger specs.

index.js
#!/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 GATEWAY = process.env.OHIP_GATEWAY_URL;   // e.g. https://your-env.hospitality-api.us-....oraclecloud.com
const CLIENT_ID = process.env.OHIP_CLIENT_ID;
const CLIENT_SECRET = process.env.OHIP_CLIENT_SECRET;
const APP_KEY = process.env.OHIP_APP_KEY;
const HOTEL_ID = process.env.OHIP_HOTEL_ID;
const SCOPE = process.env.OHIP_SCOPE;           // assigned scope for the client_credentials grant

for (const [name, v] of Object.entries({ GATEWAY, CLIENT_ID, CLIENT_SECRET, APP_KEY, HOTEL_ID })) {
  if (!v) { console.error(`Missing OHIP_${name} environment variable`); process.exit(1); }
}

// --- OAuth: POST {gateway}/oauth/v1/tokens, Basic auth + x-app-key ---
let cachedToken = null;
let tokenExpiresAt = 0;

async function getToken() {
  if (cachedToken && Date.now() < tokenExpiresAt - 60_000) return cachedToken;

  const body = new URLSearchParams({ grant_type: "client_credentials" });
  if (SCOPE) body.set("scope", SCOPE);

  const basic = Buffer.from(`${CLIENT_ID}:${CLIENT_SECRET}`).toString("base64");
  const res = await fetch(`${GATEWAY}/oauth/v1/tokens`, {
    method: "POST",
    headers: {
      Authorization: `Basic ${basic}`,
      "x-app-key": APP_KEY,
      "Content-Type": "application/x-www-form-urlencoded",
      Accept: "application/json",
    },
    body,
  });

  if (!res.ok) {
    throw new Error(`OHIP token request failed ${res.status}: ${await res.text()}`);
  }
  const data = await res.json();
  cachedToken = data.access_token;
  tokenExpiresAt = Date.now() + (data.expires_in ? data.expires_in * 1000 : 50 * 60_000);
  return cachedToken;
}

async function ohipGet(path, params = {}) {
  const token = await getToken();
  const url = new URL(`${GATEWAY}${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.toString(), {
    headers: {
      Authorization: `Bearer ${token}`,
      "x-app-key": APP_KEY,
      "x-hotelid": HOTEL_ID,
      Accept: "application/json",
    },
  });
  if (!res.ok) {
    throw new Error(`OHIP API ${res.status} on ${path}: ${await res.text()}`);
  }
  return res.json();
}

const server = new McpServer({ name: "opera-cloud", version: "1.0.0" });

// Tool 1: Housekeeping room status overview
server.tool(
  "get-housekeeping-overview",
  "Get the housekeeping status of rooms at the property: clean, dirty, inspected, pickup, plus front office status and room assignment. Supports filtering by housekeeping or front office room status. Use this for any 'what state are the rooms in' question.",
  {
    housekeepingRoomStatus: z.string().optional()
      .describe("Optional filter, e.g. Clean, Dirty, Inspected, Pickup"),
    limit: z.number().optional().describe("Max rooms to return (default 50)"),
  },
  async ({ housekeepingRoomStatus, limit }) => {
    const data = await ohipGet(`/hsk/v1/hotels/${HOTEL_ID}/housekeepingOverview`, {
      housekeepingRoomStatus,
      limit: limit ?? 50,
    });
    return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
  }
);

// Tool 2: Housekeeping vs front office discrepancies
server.tool(
  "get-room-discrepancies",
  "List rooms where the housekeeping status does not match the front office status (skips and sleeps). These are the rooms most likely to cause a bad check-in. Returns the discrepancy type per room.",
  {},
  async () => {
    const data = await ohipGet(`/hsk/v1/hotels/${HOTEL_ID}/housekeepingDiscrepancies`);
    return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
  }
);

// Tool 3: Out of order rooms
server.tool(
  "get-out-of-order-rooms",
  "List rooms currently Out of Order at the property, with reason codes and date ranges. Out of Order rooms are removed from inventory entirely.",
  {},
  async () => {
    const data = await ohipGet(`/hsk/v1/hotels/${HOTEL_ID}/rooms/outOfOrderRooms`);
    return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
  }
);

// Tool 4: Search reservations
server.tool(
  "search-reservations",
  "Search reservations at the property by arrival date range. Returns guest, room type, status, and stay dates. Use with get-housekeeping-overview to compare arrivals against room readiness.",
  {
    arrivalStartDate: z.string().optional().describe("YYYY-MM-DD, start of arrival window"),
    arrivalEndDate: z.string().optional().describe("YYYY-MM-DD, end of arrival window"),
    limit: z.number().optional().describe("Max reservations to return (default 50)"),
  },
  async ({ arrivalStartDate, arrivalEndDate, limit }) => {
    const data = await ohipGet(`/rsv/v1/hotels/${HOTEL_ID}/reservations`, {
      arrivalStartDate,
      arrivalEndDate,
      limit: limit ?? 50,
    });
    return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
  }
);

const transport = new StdioServerTransport();
await server.connect(transport);

Endpoint honesty: the paths above (/hsk/v1/.../housekeepingOverview, /hsk/v1/.../housekeepingDiscrepancies, /hsk/v1/.../rooms/outOfOrderRooms, /rsv/v1/.../reservations, /oauth/v1/tokens) were verified against the Swagger specs in Oracle's hospitality-api-docs repo at OPERA Cloud release 26.2. Query parameters and response shapes can shift between OPERA Cloud releases, so if a filter is rejected, diff against the spec version matching your environment. Note that the similarly-named /rooms/status endpoint is a PUT (it changes room status); the read path for status is housekeepingOverview.

04

Register the server with Claude Desktop

Open your Claude Desktop config file:

macOS path
~/Library/Application Support/Claude/claude_desktop_config.json
Windows path
%APPDATA%\Claude\claude_desktop_config.json

Add the OPERA entry (merge into an existing mcpServers block if you have other guides from this series set up):

claude_desktop_config.json
{
  "mcpServers": {
    "opera-cloud": {
      "command": "node",
      "args": ["/absolute/path/to/opera-mcp/index.js"],
      "env": {
        "OHIP_GATEWAY_URL": "https://your-environment-gateway-url",
        "OHIP_CLIENT_ID": "your_client_id",
        "OHIP_CLIENT_SECRET": "your_client_secret",
        "OHIP_APP_KEY": "your_application_key",
        "OHIP_HOTEL_ID": "YOURHOTELCODE",
        "OHIP_SCOPE": "your_assigned_scope"
      }
    }
  }
}

Replace every value, then fully quit and reopen Claude Desktop. Closing the window is not enough; the config is only read at startup. Remember each of these calls is a billable OHIP transaction, at the datasheet's $10-per-10,000 rate.

Try it

"Pull the housekeeping overview and today's arrivals, then tell me which arriving reservations don't yet have a clean or inspected room, as a table."

Doesn't Oracle have its own AI for OPERA?

It does now, and it is worth being precise about what it is. On June 16, 2026, Oracle announced OPERA Cloud Assistant, described in the press release as AI capabilities embedded natively in OPERA Cloud: AI-assisted room assignment, AI-generated rate code descriptions, multilingual translation, and a conversational assistant for operational procedures and Oracle documentation, available worldwide at no additional cost to OPERA Cloud customers.

What the announcement does not include is any external agent access: no Model Context Protocol server, no connector for Claude, ChatGPT, or Copilot, no way to point a general-purpose assistant at your property data. OPERA Cloud Assistant lives inside OPERA's own screens. If you want an assistant that can join OPERA data with things outside OPERA, your spreadsheets, your inspection reports, your other systems, the OHIP-plus-MCP route in this guide is, as of July 2026, the way to get it. For how OPERA compares to Mews, Cloudbeds, apaleo, and ten other platforms on exactly this axis, see our hotel PMS open API scorecard.

Troubleshooting

Token request fails with 400 or 401

Check the three parts Oracle's OAuth spec requires: a Basic authorization header that is the base64 of ClientID:ClientSecret (with the colon, no spaces), the x-app-key header, and a form-encoded body with grant_type=client_credentials. With the client_credentials grant, the scope body parameter is required; a missing or wrong scope is the most common silent failure.

Token works, but API calls return 403

A 403 with a valid token usually means an authorization gap, not an authentication one. Confirm your application is subscribed to the specific API module you are calling (hsk and rsv for this guide) in the developer portal, and that the hotel has actually granted your application access to those APIs in its environment. Oracle's model puts that control with the property.

404 or empty results on a path that should exist

Verify the x-hotelid header and the {hotelId} in the URL path match the property code for the environment behind your gateway URL. A wrong hotel code fails in unhelpful ways. Also confirm your gateway URL has no trailing slash, since the code concatenates paths directly.

A filter parameter is rejected or ignored

OPERA Cloud API specs are versioned with the platform (the specs this guide used are marked compatible with release 26.2). Download the spec matching your environment's release from the oracle/hospitality-api-docs GitHub repo and check the parameter list for your exact version before assuming a bug.

Claude doesn't see any OPERA tools

Claude Desktop reads the config only at startup. Fully quit (Cmd+Q on macOS, right-click tray icon and Quit on Windows) and relaunch. If it is still missing, check for invalid JSON in the config, a wrong absolute path to index.js, or node not being on the PATH Claude launches with.

I want Claude to update room statuses, not just read them

The write operations exist: for example, PUT /hsk/v1/hotels/{hotelId}/rooms/status changes room status in the Housekeeping API. This guide ships read-only on purpose. If you add writes, run them as a separate MCP server with its own credentials and scopes, so an exploratory conversation can never mutate a live property by accident.

FAQ

Does Oracle OPERA Cloud have an official MCP server?

No. As of July 2026, Oracle has not published a Model Context Protocol server for OPERA Cloud or any Oracle Hospitality product. The June 2026 OPERA Cloud Assistant announcement is embedded AI inside OPERA's own workflows, not external agent access. Connecting Claude means running a thin MCP server of your own on the OHIP REST APIs, which is what this guide builds.

Is OHIP free?

For the hotel, yes in the sense that matters: according to Oracle's OHIP datasheet, a hotel's access to OHIP is included in OPERA Cloud Property Management Foundation, with no per-interface fees. The API consumer pays for usage, starting at $10 for up to 10,000 REST transactions per month, billed monthly in arrears with no upfront commitment. Business Events streaming is priced separately at $10 for up to 100,000 events per month.

Do I need to join the Oracle Partner Network?

Oracle's OHIP onboarding docs describe self-registration through the Oracle Store or a partner registration form, without listing OPN membership as a gate for OHIP itself. If you work at the hotel, you do not need any partner status; your property's existing OPERA Cloud subscription carries the entitlement. Vendors pursuing a formal validated-integration listing should expect more process than plain API access.

Can Claude change data in OPERA through this setup?

Not with this server. All four tools are GET requests. The OHIP catalog does contain write operations, so treat that as a deliberate second project with separate credentials, not a flag you flip.

How long does this take end to end?

The MCP server is an afternoon. The access is the project: OHIP registration is self-service and the developer portal is available on signup, but reaching a live property requires environment credentials and the hotel authorizing your application's API access. If you control the property, plan in days. If you are a vendor waiting on a hotel's IT queue, plan in weeks. Anyone who tells you OPERA-to-AI is a ten-minute setup has not done it.

We maintain a library of Claude connection guides for the hotel and vacation rental stack, and a RapidEye API if you want inspection results in the same conversation.