WellFred — Services in Costa Rica
Find and compare wellness, home and professional services in Costa Rica. Search providers, check availability, discover classes and events, and prepare booking requests for customer confirmation. English and Spanish; no API key required.
Hosted MCP Server
npx add-mcp 'https://app.wellfred.com/api/agent/mcp'Installs into Claude Code, Codex, Cursor and more
Documentation
WellFred agent guide
WellFred connects customers with services and providers in Costa Rica. Public agents can search, browse, inspect offerings, submit guest RFQs and prepare booking requests without an integration key.
Customer overview: Using AI assistants on WellFred.
Agent Skills discovery index publishes the downloadable wellfred-services skill using discovery v0.2.0 and a SHA-256 artifact digest.
Read the contract first
Authentication and registration discovery documents anonymous agent access, customer provisioning, and credential use for the email-verification handoff.
OpenAPI JSON contains the request and response schemas generated from application code. API reference renders that same contract. Combine its server URL with each operation path. These public endpoints live under /api/agent. Send Accept: application/json; POST bodies use Content-Type: application/json.
API catalog (/.well-known/api-catalog, RFC 9727 application/linkset+json) links this API's contract, documentation, and status endpoint for automated discovery.
ACP discovery lists the public REST services: service discovery, guest quote requests, and booking intents. Use the linked OpenAPI contract for their request and response formats. ACP checkout sessions and payment processing are not supported; booking intents require customer confirmation on WellFred.
Use only the operations listed in this public contract. Discovery and RFQs are account-free; booking intents return a confirmation link for the customer.
Browser agents (WebMCP)
WellFred pages expose the same public operations to supporting browsers through document.modelContext (or navigator.modelContext where that is the browser's home for it). No integration key or account connection is needed. Tool inputs come from the generated OpenAPI contract. Native document.modelContext.executeTool() serializes the callback's result object into a JSON string; parse it once to read the existing API result plus httpStatus and, when provided, retryAfter.
| Tool | Public operation |
|---|---|
wellfred_search_services | POST /search |
wellfred_list_categories | GET /categories |
wellfred_resolve_location | GET /locations |
wellfred_list_providers | GET /providers |
wellfred_search_providers | GET /providers/search |
wellfred_get_provider | POST /providers/profile |
wellfred_check_availability | POST /availability |
wellfred_get_quote_questions | POST /rfq/questions |
wellfred_request_quotes | POST /rfqs |
wellfred_prepare_booking | POST /booking-intents |
WebMCP uses the same public access even when someone is signed in. It does not expose private bookings, account tools, payments or direct booking creation. Provider search accepts an ids array; the adapter handles HTTP query encoding. Quote requests require an idempotencyKey. Obtain the customer's permission before submitting their request; return booking confirmation links for the customer to complete on WellFred. These tools do not navigate or complete confirmation on the customer's behalf.
Cancellation stops the browser request but cannot undo work already received by the server. If a write response is unavailable, its outcome is unknown: follow the retry guidance below. The adapter never retries automatically. Browsers without WebMCP continue to use the regular website and REST API.
Find a service
A2A discovery search
The A2A Agent Card advertises the JSON-RPC
interface at /api/agent/a2a. Use its supportedInterfaces URL and protocol
version. Send A2A-Version: 1.0 and Content-Type: application/json with a
JSON-RPC SendMessage request containing a unique id and
params.message (messageId, role: "ROLE_USER", and parts). A text part
such as {"text":"massage"} supplies the search query; a data part carries
the structured search constraints below. Results return in
result.message.parts, with structured data and a text recommendation.
This interface supports synchronous discovery search. Catalog operations, RFQs, and booking intents use the REST operations below. Streaming, push notifications, and extended Agent Cards are not supported.
REST discovery search
GET /categories: category and subcategory IDs for browsing.GET /locations?query=Uvita: candidate places with coordinates. Resolve ambiguity with the customer. A town's center is suitable for search, not an exact booking address.POST /search: ranked service offerings, their providers, structured pricing and a short recommendation. Omitqueryto browse with category/location filters.GET /providersandGET /providers/search: browse providers or resolve provider names/IDs.POST /providers/profile: inspect a public provider by business UUID.POST /availability: inspect a service's available slots for an explicit date. Request-based services may require an RFQ or provider follow-up rather than expose slots.
Interpret natural language into explicit constraints before searching. WellFred's existing text/semantic search ranks the service need; it does not reliably extract dates, currencies or headcounts from prose. For “mobile massage in Uvita tomorrow for 2 people, under ₡40k each,” resolve the location and tomorrow's date in America/Costa_Rica, then send:
{
"query": "massage",
"delivery": "in-home",
"partySize": 2,
"maxPrice": 40000,
"currency": "CRC",
"priceUnit": "person",
"limit": 5
}
Add lat, lng from the selected location and date as YYYY-MM-DD. No sample date or guessed coordinates are defaults. Tell the customer the actual date you used.
Currency filters match the offering's currency; they do not convert prices. priceUnit distinguishes per-person from per-session prices. price is the same starting price the offering page shows, so quoting it will not contradict the page you link to; for an offering with options it is the cheapest option, and maxPrice filters against that same number. A starting price is not a final quote. Date checks do not establish party capacity, and nearby providers are not proof of coverage for an exact address. Explain unresolved requirements rather than claiming every constraint has been verified. A search examines a bounded set of ranked candidates; an empty filtered result is not proof that no provider exists.
Search returns up to limit distinct business entries. Each entry retains its representative offering and an alternativeOfferings array with at most one additional primary matching offering from that business. Every offering has its own ID, URL, price, unit and nextAction; these are separate services, not pricing options of the representative. Date searches check the additional offering independently. If its check fails, it is omitted rather than replaced with another candidate.
matchQuality uses marketplace's classification: strong means primary, loose means related, and discovery means browsing/category suggestions. This describes matching, not suitability, availability or a review rating. Present primary offerings before clearly labeled related suggestions. strongResultCount counts primary offerings actually returned, including alternatives; it is not a catalog total or a count of businesses.
Return a few relevant choices with their canonical URLs. Follow nextAction: services with options should be opened on their offering page for option selection; supported single-offering services can use booking intents. Never invent IDs, quotes or availability.
Guest quote requests
An RFQ needs no customer account:
POST /rfq/questionswithrequestedServiceorsubcategoryUuid. Use the returned question keys/options, taxonomy IDs and the user's answers. No question set means use free-text intake, not “service unavailable.”- Collect name, phone country code and phone number, work requested, location and timing. Email and budget are optional. A supplied budget requires an explicit currency.
- Show the request summary and obtain permission to send it to WellFred for provider follow-up.
POST /rfqs. PreserverequestedService, resolved taxonomy, answers and anypreferredProviderUuid. Supply anidempotencyKeyand reuse the same key and payload on retries.- Give the customer the returned reference. An RFQ starts staff-assisted quote follow-up; it is not a confirmed appointment.
Example free-text request after the customer has provided these details and authorized submission:
{
"requestedService": "Repair a leaking kitchen pipe",
"location": "Uvita",
"timing": "The explicit date range agreed with the customer",
"contactName": "Customer-provided name",
"contactPhoneCountryCode": "+506",
"contactPhoneNumber": "Customer-provided phone number",
"idempotencyKey": "A unique identifier for this request"
}
Replace the descriptive placeholders with real user-provided values. RFQ success responses contain success, message, rfqUuid, reference and created at the top level. created: false means the submission was replayed.
Booking with email verification
- Choose an offering and a specific time. Obtain approval for the request and known price/currency.
POST /booking-intentswithserviceId,startIso(ISO 8601 with timezone offset), optionalpartySize, and the customer's exactorigincoordinates for in-home visits. An intent is an expiring request, not a booking or a held slot. Repeated preparation creates separate intents: reuse the returned confirmation link rather than prepare repeatedly.- Return
confirmUrlto the customer. On WellFred, an existing verified customer can confirm directly. Otherwise the customer supplies their name/email and receives the existing secure email login link. A free account is created if needed, with disclosure on the form. - The email link returns to the saved request. Only the verified customer can submit it. WellFred rechecks time and price and uses the normal booking service. Repeated confirmation of the same intent returns the same booking result.
- The confirmation page reports the outcome. A pending request still needs provider acceptance. No payment is collected by this API.
Do not ask for passwords or claim that supplying an email proves ownership. The public API never returns a login token or exposes customer booking history. The email and final confirmation steps take place on WellFred; no ChatGPT account connection is required for this handoff.
Existing booking rules still apply, including verified-phone requirements after the first booking. If an intent expires, prices change, or the offering needs option selection, return to the offering or prepare a fresh request and obtain approval for the new details. Do not silently substitute services or prices.
Errors and retries
Every operation answers in the same envelope: success plus message, with the operation's own fields beside them at the top level. A failure sets success: false and names the reason in error_code — read that, not the prose in message, when branching.
Read JSON validation errors on 422 and correct only the invalid inputs. Respect 429 responses and Retry-After. Requests have bounded sizes and rate limits. A 503 with error_code: CONCIERGE_DAILY_CAP_REACHED means the discovery and quote-question operations are paused for the day; the rest of the API still answers, and the customer can continue on the website. Inspect success and the operation-specific outcome fields as well as the HTTP status before reporting success. Never retry a write with a different RFQ key or a fresh booking intent just because the original response was lost.