Skip to main content
HigginbothamMedia

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

EndpointAuthenticationExposes
https://hig.media/api/mcpNoneThe four public read-only tools.
https://hig.media/api/mcp/accountOAuth 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.

  1. Read the discovery documents: https://hig.media/.well-known/oauth-authorization-server (RFC 8414) and https://hig.media/.well-known/oauth-protected-resource (RFC 9728). A request to the account endpoint without a token answers 401 with a WWW-Authenticate header that points at the second document.
  2. Register the client with POST https://hig.media/api/oauth/register (RFC 7591 dynamic registration), sending a client_name and one to ten redirect_uris. Every URI must be https or a loopback http://localhost address. Clients are public: no secret is issued, and PKCE is the proof of possession.
  3. Send the customer to https://hig.media/oauth/authorize with response_type=code, the registered client_id and redirect_uri (matched exactly), a code_challenge with code_challenge_method=S256, and an optional state.
  4. 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.
  5. Exchange the authorization code at POST https://hig.media/api/oauth/token with the PKCE verifier. The response carries a one-hour access token, a refresh token and the account scope.
  6. Send the access token as Authorization: Bearer to https://hig.media/api/mcp/account. Refresh it at the token endpoint with grant_type=refresh_token when it expires.

Expected behavior

  • Each endpoint allows 60 requests per 10 minutes per IP address. Past that it answers 429 with a Retry-After header and a JSON-RPC error rather than an empty body. Client registration allows 10 attempts per 10 minutes per address, and create_booking allows 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_availability reads 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_booking creates 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 account scope 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. whoami returns name and email, nothing else on the record. list_my_galleries says whether a gallery needs a passcode but never returns it.
  • get_booking_details can return a property’s gate or lockbox code, because correcting one is what the tool is for. Those codes never appear in list_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_unavailable from an OAuth endpoint
The server’s OAuth signing secret is not configured. Nothing on the client side fixes it; contact the studio.
401 from the account endpoint
The bearer token is missing, invalid, expired, or does not carry the account scope. Refresh the token, or reconnect if the refresh token has also expired.
400 invalid_grant from 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_uri or a consent page that says the app cannot connect
The redirect_uri is not one the client registered (an exact match is required), or the PKCE parameters are malformed. Re-register or correct the request.
429 from 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_details or get_booking_details; a name the form does not define is reported back unsaved.

Revised September 3, 2026. Questions about the integration: tracey@higginbothammedia.com.