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
Published Higginbotham Media photography and media services for the Treasure Coast and Palm Beaches: names, starting prices in USD, durations, and informational service pages. This tool does not book or purchase anything.
get_service_detailsService details
Published details for one Higginbotham Media service by slug: USD pricing, scheduling limits, inclusions, and non-sensitive planning questions that can affect price. Property access credentials are excluded, and this tool does not book or purchase anything.
get_availabilityCheck availability
Open appointment slots for a published service on a real calendar date (YYYY-MM-DD) in America/New_York time. Returns an informational service page and explains unavailable dates. It does not accept an address, hold a slot, create a booking, or send a notification.
get_studio_infoStudio info
Higginbotham Media's published studio identity, owner, contact email, Treasure Coast and Palm Beaches service areas, and informational website links.

Account tools

Account endpoint only. Each one answers for the connected customer and takes no argument that could point it at anyone else. A customer on a team also sees the team’s bookings, exactly as the account page shows them: every member can read them, and a team lead can act on them.

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. For each team the customer is on, a `teams` entry (with the team's id and name) lists that team's bookings made by teammates (who booked each, and whether this customer, as a lead of that team, may reschedule or cancel them). A teammate's personal bookings and other customers' bookings are never included.
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 and expiry date, qualifying spend, reward picks remaining and allowance, 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 and counterpart name. 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 creating a booking: base price, intake-question adjustments, travel fee, and any coupon, loyalty reward, or referral credit that would apply. Coupon attempts consume a private rate-limit budget, and a calendar failure can alert the studio owner by email. Use get_service_details first for the non-sensitive intake questions a service asks. Shoot-detail answers (intakeAnswers) are keyed by the form's exact field names: a number question takes a whole number, sent as a number or a digit string; a checkbox takes true or false; every other question takes a string, and an empty string clears an answer.
create_bookingRequest a booking
Request a shoot for this signed-in customer at a specific date and time. Creates a pending booking, emails the customer and studio, and can queue calendar, invoice, loyalty, referral, and property-access synchronization. Before calling, obtain explicit customer confirmation of the selected service, date and time, property address, quoted price, and notification effects. The studio reviews and confirms it by email; retries can create duplicate requests. After an uncertain response, reread the customer's bookings before considering another request. Limited to 5 successful requests per day. Shoot-detail answers (intakeAnswers) are keyed by the form's exact field names: a number question takes a whole number, sent as a number or a digit string; a checkbox takes true or false; every other question takes a string, and an empty string clears an answer.
reschedule_bookingReschedule a booking
Move one manageable booking to a new date and time, optionally changing its service. A team lead may move a team booking listed by list_my_bookings. The write sends notifications and can update downstream calendar and invoice state; a confirmed or canceled booking returns to pending. Confirm the exact change before calling, and do not retry after an uncertain response without first rereading the booking. Shoot-detail answers (intakeAnswers) are keyed by the form's exact field names: a number question takes a whole number, sent as a number or a digit string; a checkbox takes true or false; every other question takes a string, and an empty string clears an answer.
get_booking_detailsBooking details
The non-sensitive shoot details and price breakdown recorded for one manageable booking. A team lead may read a team booking listed by list_my_bookings. Property access credentials are always redacted from the response.
update_booking_intakeUpdate shoot details
Correct non-sensitive shoot details on one manageable booking, such as square footage or story count. Property access credentials cannot be sent through this MCP. Answers are merged over stored values, the total is recomputed, the customer and studio receive a change email, and invoice synchronization can be queued; this path skips direct calendar synchronization. A price change can return a confirmed booking to pending. Obtain explicit customer confirmation of the correction and explain possible repricing and notifications before calling. After an uncertain response, reread the booking before considering a retry. Shoot-detail answers (intakeAnswers) are keyed by the form's exact field names: a number question takes a whole number, sent as a number or a digit string; a checkbox takes true or false; every other question takes a string, and an empty string clears an answer.
cancel_bookingCancel a booking
Cancel one manageable booking after explicit customer confirmation. A team lead may cancel a team booking listed by list_my_bookings. This sends notifications and can void a linked invoice; it cannot be undone from this tool. Do not retry after an uncertain response without first rereading the booking.

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 without accepting a raw address or precise location. 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. This lookup does not send an outage notification.
  • 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 canceled 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, plus the team bookings a team member can already see on the account page. A teammate’s personal bookings are never included. whoami returns name and email, nothing else on the record. list_my_galleries says whether a gallery needs a passcode but never returns it.
  • Property gate and lockbox codes are excluded from MCP question definitions, redacted from booking details, and refused if a client attempts to send them. Customers use the secure website workflow for those values.
  • 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.
  • Property access credentials cannot be read or written 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. A number question accepts a whole number sent as a number or a digit string, a checkbox accepts true or false, and an answer that fails is named in the refusal along with the reason.

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