For AI agents
The Higginbotham Media MCP server
A Model Context Protocol interface for agents and MCP-compatible desktop clients: read the service catalog and live availability without signing in, or connect a customer account to see and manage that customer's own bookings and galleries.
What it is for
Higginbotham Media is a real-estate media studio based in Jupiter, FL, serving Florida’s Treasure Coast and The Palm Beaches. The MCP server lets an assistant answer the questions a listing agent asks before booking (what is offered, what it costs, when the studio is free, what a shoot at a given address would run) and, once a customer has connected their account, act on that customer’s behalf: preview a quote, request a shoot, correct the shoot details, reschedule or cancel.
Everything an agent can read here is also on this website, and every booking action follows the same rules as the booking flow. The server exposes tools only: no prompts, no resources, no staff functions, no payments.
Endpoints
| Endpoint | Authentication | Exposes |
|---|---|---|
https://hig.media/api/mcp | None | The four public read-only tools. |
https://hig.media/api/mcp/account | OAuth 2.1 bearer token (PKCE) | The public tools plus the account and booking tools, scoped to the connected customer. |
Both endpoints speak MCP over streamable HTTP and are stateless: every JSON-RPC request is a standalone POST, no session is established, and subscriptions are not offered. The tools an MCP client lists are exactly the ones below.
Tools
Public tools
Available on both endpoints without a token. Read-only.
list_servicesList services- All bookable photography/media services from Higginbotham Media (Treasure Coast & Palm Beaches real-estate photography): names, prices, durations, and booking links.
get_service_detailsService details- Full details for one service by slug: pricing, scheduling limits, what's included, and the intake questions the booking flow asks (some answers adjust the price).
get_availabilityCheck availability- Open appointment slots for a service on a date (YYYY-MM-DD, US Eastern studio time). Pass the property address to include a travel-fee estimate. Book at the returned bookingUrl. When a date has no slots, unavailableReason and unavailableNote say why — a temporary calendar fault reads differently from a closed or fully-booked day. For a signed-in customer, a slot marked mine:true is blocked by that customer's OWN booking, so a day is not necessarily full to them.
get_studio_infoStudio info- Who Higginbotham Media is: owner, contact email, service areas (counties and cities), and canonical site links.
Account tools
Account endpoint only. Each one answers for the connected customer and takes no argument that could point it at anyone else.
whoamiWho am I- The signed-in Higginbotham Media customer's name and email, for the agent to confirm which account it's connected as.
list_my_bookingsList my bookings- This signed-in customer's own bookings, split into upcoming and past: service, date, status, property address, quoted total, and a link to the delivered gallery once one exists. Never includes a teammate's or another customer's bookings.
list_my_galleriesList my galleries- Galleries this signed-in customer can view: title, shoot date, property address, and the client gallery link. Notes whether a gallery requires a passcode to open, but never returns the passcode itself.
get_loyalty_statusLoyalty status- This signed-in customer's Higginbotham Media Rewards status: tier, reward picks remaining, and the reward menu their tier can redeem. Says plainly when the rewards program isn't currently active, rather than an empty-looking result.
get_referral_infoReferral info- This signed-in customer's own referral code, the program's current discount percentage, and any available referral credit with its expiry date. Never another customer's referral code.
Booking tools
Account endpoint only. A refusal (a slot already taken, a date past the booking horizon, a change inside the cutoff, a rejected coupon) comes back as an ordinary tool result marked as an error, with the studio’s own wording first, so an agent can relay it and recover rather than treat it as a protocol failure.
preview_bookingPreview a booking- Price a shoot without booking it: base price, intake-question adjustments, travel fee, and any coupon, loyalty reward, or referral credit that would apply. Writes nothing — call create_booking to actually request the slot. Use get_service_details first for the intake questions a service asks.
create_bookingRequest a booking- Request a shoot for this signed-in customer at a specific date and time. Creates a PENDING booking request — Higginbotham Media reviews and confirms it by email, and the slot is not held until they do. Check get_availability first, and preview_booking to confirm the price. Limited to 5 requests per day.
reschedule_bookingReschedule a booking- Move one of this customer's own bookings to a new date and time, optionally changing the service. Subject to the studio's cutoff: a shoot starting within 12 hours can no longer be changed online. A confirmed booking returns to pending for re-approval. Use list_my_bookings for booking ids.
get_booking_detailsBooking details- Everything recorded against one of this customer's own bookings: the shoot details they answered (square footage, story count, and any gate or lockbox code the property needs), the questions those answers belong to, and the full price breakdown. Read this before calling update_booking_intake so you correct the right field. Note the response can contain property access codes.
update_booking_intakeUpdate shoot details- Correct the shoot details on one of this customer's own bookings — square footage, story count, gate or lockbox code — without cancelling and rebooking. Answers are MERGED over what is already stored, so send only the ones that change; send an empty string to clear one. Field names must match this service's form exactly (get_booking_details lists them); anything else is reported back unsaved rather than applied. The quoted total is recomputed, and if it changes on a confirmed booking that booking returns to pending for the studio to re-approve. Details that do not affect the price can be updated right up to the shoot; a price change within 12 hours of it has to go through the studio.
cancel_bookingCancel a booking- Cancel one of this customer's own bookings. Subject to the same 12-hour cutoff as rescheduling. This cannot be undone from here — a cancelled booking can only be revived by rescheduling it. Use list_my_bookings for booking ids.
How to connect
Public access
Point an MCP client that supports streamable HTTP at https://hig.media/api/mcp. No registration, key or token is needed.
Account access
Account access uses OAuth 2.1 with PKCE. Most MCP hosts complete these steps on their own once given the server URL; they are listed so a client author can check each one.
- Read the discovery documents:
https://hig.media/.well-known/oauth-authorization-server(RFC 8414) andhttps://hig.media/.well-known/oauth-protected-resource(RFC 9728). A request to the account endpoint without a token answers401with aWWW-Authenticateheader that points at the second document. - Register the client with
POST https://hig.media/api/oauth/register(RFC 7591 dynamic registration), sending aclient_nameand one to tenredirect_uris. Every URI must behttpsor a loopbackhttp://localhostaddress. Clients are public: no secret is issued, and PKCE is the proof of possession. - Send the customer to
https://hig.media/oauth/authorizewithresponse_type=code, the registeredclient_idandredirect_uri(matched exactly), acode_challengewithcode_challenge_method=S256, and an optionalstate. - The customer signs in to their Higginbotham Media account and approves the app on a consent page. Signing in is done on this site, never inside the client.
- Exchange the authorization code at
POST https://hig.media/api/oauth/tokenwith the PKCE verifier. The response carries a one-hour access token, a refresh token and theaccountscope. - Send the access token as
Authorization: Bearertohttps://hig.media/api/mcp/account. Refresh it at the token endpoint withgrant_type=refresh_tokenwhen it expires.
Expected behavior
- Each endpoint allows 60 requests per 10 minutes per IP address. Past that it answers
429with aRetry-Afterheader and a JSON-RPC error rather than an empty body. Client registration allows 10 attempts per 10 minutes per address, andcreate_bookingallows 5 requests per customer per day. - Access tokens expire after one hour. Refresh tokens last 30 days and are rotated on every use: the old one stops working the moment a new pair is issued. Authorization codes are single-use.
get_availabilityreads the studio calendar live and quotes a travel-fee estimate for an address; the booking flow recomputes the fee authoritatively. For a connected customer it also applies their loyalty booking horizon and marks slots held by their own bookings, so a day blocked only by their shoot is not reported as full. When a date has no slots it says why, and a temporary calendar fault is reported as a fault, not as a fully booked day.create_bookingcreates a pending request. The studio reviews and confirms it by email, and the slot is not held until then. Rescheduling, or a shoot-detail change that alters the price on a confirmed booking, returns it to pending for re-approval. A shoot starting within 12 hours can no longer be changed or cancelled online.- A tool that fails for a reason the caller cannot fix (a database or calendar fault) returns a generic message and logs the detail on the server only.
Authentication boundaries
- Only a verified customer, signed in to their own account, can approve a connection. A staff sign-in is refused on the consent page, and so is a staff member viewing a customer’s account through impersonation.
- The customer identity behind every account tool comes from the verified token, never from a tool argument. No tool accepts a customer id, email or name as input.
- The
accountscope is the only scope. There are no staff or administrative scopes and no tools that reach another customer’s records. - Rotating the server’s signing secret invalidates every access token in flight; refresh tokens are unaffected and mint a fresh access token transparently.
Privacy
- The public endpoint returns the same catalog, pricing and availability the website shows. It never attributes a booked slot to anyone.
- Account tools return the connected customer’s own data only.
whoamireturns name and email, nothing else on the record.list_my_galleriessays whether a gallery needs a passcode but never returns it. get_booking_detailscan return a property’s gate or lockbox code, because correcting one is what the tool is for. Those codes never appear inlist_my_bookings.- No tool exposes payment details.
- Authorization codes and refresh tokens are stored as hashes. A customer who wants a connected app removed can ask the studio to revoke it; access already issued lapses within the hour.
- A booking requested through an agent is recorded with the same attribution as one made on the website. See the privacy policy for what the site collects in general.
Troubleshooting
503 temporarily_unavailablefrom an OAuth endpoint- The server’s OAuth signing secret is not configured. Nothing on the client side fixes it; contact the studio.
401from the account endpoint- The bearer token is missing, invalid, expired, or does not carry the
accountscope. Refresh the token, or reconnect if the refresh token has also expired. 400 invalid_grantfrom the token endpoint- The code or refresh token was already used, has expired, was issued to a different client or redirect URI, or does not match the PKCE verifier. The response is the same in every one of those cases on purpose; start the flow again.
400 invalid_redirect_urior a consent page that says the app cannot connect- The
redirect_uriis not one the client registered (an exact match is required), or the PKCE parameters are malformed. Re-register or correct the request. 429from any endpoint- A per-address or per-customer limit was reached. Wait the number of seconds in
Retry-After. - The consent page refuses a staff or impersonated session
- Only the customer can approve the connection, from their own sign-in. Ask them to open the authorize link themselves.
- A tool result marked as an error
- Read the first line: it is the studio’s own explanation (an unknown service, a slot no longer open, a cutoff, a rejected coupon, an intake answer the form does not define). Structured detail follows where there is any.
Limitations
- The property address on an existing booking cannot be changed, because it moves the travel fee and the drive-time math. Cancel and rebook instead.
- No staff or administrative tools are exposed.
- Tools only: no MCP prompts or resources are implemented.
- No payment actions are available through MCP.
- Booking creation follows the normal studio workflow and remains pending until the studio confirms it.
- Field names for shoot details come from each service’s intake form and must be read from
get_service_detailsorget_booking_details; a name the form does not define is reported back unsaved.
Revised September 3, 2026. Questions about the integration: tracey@higginbothammedia.com.