Surfing Dog Search
Measured conclusion: Deep-tested. L2 outcome: tools_ok.
Find businesses an AI agent can message, book or buy from, and check what an agent can do on a site.
| Author | ai.surfingdog |
|---|---|
| Access | remote |
| Publisher key required | No |
| Measured state | Deep-tested |
| L1 liveness | alive |
| L1 latency | 2465 ms |
| Last measured | 2026-10-24 |
Add to your agent
Copy this into your MCP client config:
{
"mcpServers": {
"Surfing Dog Search": {
"url": "https://surfingdog.ai/mcp",
"transport": "streamable-http"
}
}
}
Measured tools (14)
search_businessesread-onlyFind businesses in the directory by what they do (query, category: a group or a place category), where (near, country), the language they speak, whether they are open now, their attributes (list_attributes), price band, what their doors take and how they are paid (accepts: kinds, and ways to pay such as card, apple_pay, paypal or x402; each result's accepts.pay_with says whether the business declared each or it was only seen, on its site or in its shop platform's standard profile, and where), whether a door answers asks or quotes (requestable), the type of door, their readiness level, whether they have an inbox, and whether they are members, registered or found. Results come in the directory's published order, which nobody can pay to change; every filter only leaves businesses out. This server takes no orders or payments and books nothing itself: request_booking asks a business's own inbox for a time, and the business confirms it there. Each result lists the business's own doors. A business this network found on its own website is marked as found, with the date it was checked; a local one is listed once its site is matched to its entry on public maps or in a business register, or its owner proves the site is theirs. Software, API and AI companies (category software-ai) are kept apart: they come only when category names that group or one of its categories, query names their kind, or every word of query is in one's name. Pages of up to 20; pass next_cursor as cursor for more.
Parameters:
near— object — Only businesses within radius_km of this point, each with its distance.level— string — At this readiness level or above: askable (an AI can ask), bookable (a door takes bookings), orderable (a door takes orders), payable. bookable and orderable are one rung, and each asks for what the doors take. Nothing below askable is listed yet. This only leaves businesses out.limit— integer — How many to return: 10 when left out.order— string — rank: the published order (the default); nearest: by distance, and it needs near.query— string — A few words about what the business does or where, like "florist" or "coffee singapore". Every word must match its name, town, description, categories, tags or services, ignoring capitals and accents. Words like "open" or "near me" belong in open_now and near instead.cursor— string — next_cursor from the previous answer, for the next page of the same search.source— array — member (through its inbox), registered (by the business), found (by this network on the business's own website); any of them. This only leaves businesses out.accepts— array — What its live doors take and what it accepts as payment, all of them: ask, quote, book, order, pay, or a payment from list_attributes like card or pix. This only leaves businesses out.country— string — A country code like PT or BR: a business located there, serving it or shipping there. This only leaves businesses out.category— string — A slug from list_categories, like hair-beauty, or a place category id like hair_salon, with every category below it. Its label or a synonym works too. Under rules before version 7 any other word matches the tags businesses gave themselves; from version 7 it is an error that names up to 5 categories to try.language— string — Only businesses that speak this language, as a tag like pt or en; pt also finds pt-br.open_now— boolean — true: only businesses open right now by the hours they published. One that published no hours is left out.door_type— array — A live door of any of these types: inbox, mcp, a2a, openapi, api, ucp, acp, nlweb, other, "platform" for any platform, or platform:<name>. This only leaves businesses out.has_inbox— boolean — true: with an inbox door; false: without one. This only leaves businesses out.item_type— string — Only businesses whose inbox takes this.attributes— array — Keys from list_attributes, like "delivery" or "walk_ins", or key=value for one with values; every one must hold. This only leaves businesses out.price_band— string — 1 (cheapest) to 4, as "2" or a range "1-2". This only leaves businesses out.requestable— string — A live door that declared it answers this kind. This only leaves businesses out.
Hints: read-only yes · destructive no · idempotent yes · open-world no
get_businessread-onlyOne business's full listing, by its domain: its address (a town and country for one this network found), the week's opening hours and closures, its doors and what each takes, its services, its standing in words, a member's track record (promises kept, broken and still open, and when, once enough have closed; self_reported when it rests on the business's own word, with no score and no count of customers), and how many of its promises closed with each outcome; for one that is not a member, every fact with its source and date; and its doors' history from this network's own reads: when each was first and last seen answering, and on how many days, and for a door read every day (a member's, a claimed listing's), from 14 days checked, the share of days every check answered, as a count and a share ("answered 41 of 42 days (97%)"): a day with a failed or a refused check counts as a missed day, and a refused one is shown as refused. This server takes no orders or payments; the listing names the business's own doors, and request_booking can ask its inbox for a time. Its agentic score, if checked, is at https://surfingdog.ai/b/<domain>. Capability ids are defined at https://surfingdog.ai/spec/capabilities/.
Parameters:
domain(required) — string — The business's domain, like ana-salon.example, as search_businesses gave it.
Hints: read-only yes · destructive no · idempotent yes · open-world no
check_businessChecks what an AI agent can do with a business's website: message, book, order, sign up, pay, change or cancel. Waits up to 25 seconds; if the read isn't finished, returns what it found so far, and you call it again for the score. A result read in the last hour is answered as it is; after a business changes its site, set fresh to true to read it again (allowed a few minutes after the last read). A done result also carries door_history: what this network's own reads found of the site's doors, kept for good: when each was seen answering and on how many days, and for a door read every day (a member's, a claimed listing's), from 14 days checked, the share of days every check answered, as a count and a share ("answered 41 of 42 days (97%)"): a day with a failed or a refused check counts as a missed day, and a refused one is shown as refused. Use it when a person asks how agent-ready a business is, or wants to improve their own. To find businesses, use search_businesses instead. A setup link in the answer is for the owner to fill in themselves. Capability ids are defined at https://surfingdog.ai/spec/capabilities/.
Parameters:
url(required) — string — The business's website, as a URL or a bare domain like salon.example.fresh— boolean — Read the site again rather than answer the stored result: for a business that just changed its site. Allowed a few minutes after the last read; before that, the stored result is answered with when to ask again.
Hints: read-only no · destructive no · idempotent yes · open-world yes
report_doorRecords how a business's door went (its inbox, MCP, A2A or API) when you used one: it answered (ok), refused (slot_taken, out_of_stock…), the request was your own fault (invalid), it failed (could not connect, a server or tool error), or it needs a person (info); up to 100 uses in one call. A report is private to the business and may make this network check a door that agents say is down (at most twice a day per door, for the doors it reads itself); it changes nothing public by itself, and carries no person and nothing that was said. Reports signed with your own key or your platform's, about businesses your own signed searches here returned, earn a larger reading allowance (this network's /report.md).
Parameters:
v(required) — numberreports(required) — array
Hints: read-only no · destructive no · idempotent yes · open-world yes
ask_businessSends your person's question to a business's own inbox, as a message. Only for a business in this directory with its own inbox (its listing names one), and only when your person asked you to contact it. The business can answer your person by email, at the address they agreed to give it; never a phone number. This network carries the request and keeps only a record that it was delivered. The answer is the inbox's: the business's own words, and an access token to read the request's state.
Parameters:
domain(required) — string — The business's domain, as search_businesses or get_business gave it, like bikes.example.message(required) — string — What your person wants to ask, in their words.contact(required) — object — Where the business can answer. Only an email address and a name: never a phone number.consent(required) — boolean — true only when your person agreed to give this business their email address for its answer. Without it nothing is sent.subject— string — A few words the business sees first.language— string — The language your person wants the answer in, as a tag like en, pt or pt-BR.
Hints: read-only no · destructive no · idempotent yes · open-world yes
request_quoteAsks a business for a price, in its own inbox, for something your person describes. Only for a business in this directory with its own inbox (its listing names one), and only when your person asked you to contact it. The business can answer your person by email, at the address they agreed to give it; never a phone number. This network carries the request and keeps only a record that it was delivered. The answer is the inbox's: the business's own words, and an access token to read the request and its quote.
Parameters:
domain(required) — string — The business's domain, as search_businesses or get_business gave it, like bikes.example.what(required) — string — What the quote is for, in a few words: Wheel rebuild, Kitchen tiling.details(required) — string — What the business needs to know to give a price.contact(required) — object — Where the business can answer. Only an email address and a name: never a phone number.consent(required) — boolean — true only when your person agreed to give this business their email address for its answer. Without it nothing is sent.language— string — The language your person wants the answer in, as a tag like en, pt or pt-BR.quantity— integer — How many, when it is a number of things.needed_by— string — The date your person needs it by, as YYYY-MM-DD.
Hints: read-only no · destructive no · idempotent yes · open-world yes
request_bookingWithout start: the business's free times for one of its services, read from its own inbox; nothing is sent. With start: asks the business's own inbox to book that time for your person. A priced service first answers with its terms (confirm): show them to your person, and send terms_sha only after their yes. Only for a business in this directory with its own inbox (its listing names one), and only when your person asked you to contact it. The business can answer your person by email, at the address they agreed to give it; never a phone number. This network carries the request and keeps only a record that it was delivered.
Parameters:
domain(required) — string — The business's domain, as search_businesses or get_business gave it, like bikes.example.service(required) — string — The service's name, as get_business lists it, or its id from this tool's answer.from— string — Without start: the first day to show free times for (today when left out).notes— string — Anything the business should know.start— string — When your person wants it to start, from this tool's free times. Leave it out to see them first.consent— boolean — Needed with start: true only when your person agreed to give this business their email address.contact— object — Needed with start: where the business can answer.language— string — The language your person wants the answer in, as a tag like en, pt or pt-BR.terms_sha— string — The confirm.terms_sha of the last answer, sent only after your person said yes to its summary.party_size— integer — How many people it is for, when that matters.
Hints: read-only no · destructive no · idempotent yes · open-world yes
list_categoriesread-onlyThe categories list: every slug with its English and Portuguese labels and its kind (local_and_retail, or software_and_ai for software, API and AI companies, kept apart). Pass a slug as category to search_businesses.
Hints: read-only yes · destructive no · idempotent yes · open-world no
list_attributesread-onlyThe attributes a search may ask for (delivery, walk_ins, wifi…), each with its labels, and the payments accepts takes. Pass keys as attributes to search_businesses, and payments as accepts.
Hints: read-only yes · destructive no · idempotent yes · open-world no
get_censusread-onlyMonthly counts of what AI agents can do at the websites this network checked: how many an agent can message, book, order from or pay, through which doors, by country, kind of business (group), website platform, where the sites came from (source) or city. Counts only; no business is named. Without edition, the latest published one; without scope, the whole; with a scope and no key, each key's headline counts; with a key, all of its counts. Open data under CC BY 4.0: credit "Surfing Dog census, surfingdog.ai, CC BY 4.0", and "© Overture Maps Foundation" with city counts. Capability ids are defined at https://surfingdog.ai/spec/capabilities/.
Parameters:
key— string — One key of the scope: a country code (GB), a group slug, a platform slug, a source, or a city slug (madrid). Without it, every key of the scope with its headline counts.scope— string — all (the default), country, group (kind of business), platform, source (where the sites came from) or city.edition— string — The month, YYYY-MM. Without it, the latest published edition.
Hints: read-only yes · destructive no · idempotent yes · open-world no
register_businessFor a business's own AI: put the business in this directory with its doors (MCP, A2A, OpenAPI, an API, UCP, ACP, a platform's door) and its facts: name, what it is (a category of list_categories or a place category, and one line), where (a storefront, a service area, or online with the countries it ships to), its languages, and agree. One call when its proof is already in place; otherwise the answer gives a challenge to put on its domain (a well-known file, its inbox manifest, a DNS record), a key's signature, or a code sent to an address at its domain, and the next call proves it. The answer names every part not taken and why, its readiness level, and what the next level takes. Doors count once this network's crawler has checked them; a door on another host counts only when the site leads to it or its own document names the business's domain. Mail, phone, messaging, forms and web pages are never doors. Every kind of business is listed except adult services, gambling, weapons, tobacco, cannabis and vaping, payday loans and bail bonds. agree accepts the listing terms (/bot#terms). Being listed is free, and nothing about the order can be bought.
Parameters:
domain(required) — string — The business's own website domain. A business without a website is not supported yet.name(required) — string — As the business writes it.category(required) — object — What the business is: one category, and at most two more.description(required) — string — One line on what it does; the first line is at most 160.where(required) — object — A storefront needs an address or geo, a service area its radius or countries, online its ships_to.languages(required) — array — Language tags, like pt or fr-CA.agree(required) — boolean — The business agrees to be listed by the network's published rules (GET /v1/ranking) and listing terms.pay— array — Payment tokens of list_attributes.doors— arrayhours— object — As a profile's hours: {"timezone": "Europe/Paris", "weekly": {"tue": [["09:00", "19:00"]]}}.proof— objectlocale— string — The language to answer in.attributes— object — Keys of list_attributes.currencies— array — ISO 4217.price_band— integer — 1 (cheapest) to 4.want_inbox— booleanclaim_token— string — Given by a successful register_business: proof again for 90 days, for this listing only.alternate_names— array — Other names the business goes by; a name longer than the network keeps is dropped (the reference network keeps 60 characters and 4 words at most).
Hints: read-only no · destructive no · idempotent no · open-world yes
update_businessdestructiveFor a business's own AI: correct its listing (set any field register_business takes), add or remove doors, turn the listing off or on, or hide its agentic score result (score_page), with its claim_token or a proof as register_business asks. opt_out stops this network listing the site (list), reading it (crawl), or both (all). With no proof it removes only a listing nobody claimed; a claimed or registered listing is taken out only with its claim_token or a proof as strong as its claim.
Parameters:
domain(required) — stringset— object — Any field register_business takes, but domain.doors— objectproof— objectlisting— string — off hides it from search and keeps it in the index.opt_out— object — Stops the listing (list), the crawl (crawl) or both (all). Without a claim token or a proof it removes an entry the network found that nobody claimed, and never a claimed or registered listing, which needs its claim_token or a proof as strong as its claim. A business that opted out comes back with a domain or key proof.score_page— string — hidden takes the business's agentic score result page out of view, its ranks and leaderboards included; shown brings it back. It needs the claim token or a proof, as set does.claim_token— string — Given by a successful register_business: proof again for 90 days, for this listing only.
Hints: read-only no · destructive yes · idempotent no · open-world yes
start_inboxread-onlyFor a business's own AI: the link where the business's owner sets up their own agent inbox, hosted by Surfing Dog, at inbox.<domain>. Give the owner the link; they check the details and type their own email there. This tool never signs anyone up and takes no email. It says so when the business already runs an inbox, or when one cannot be hosted for the domain (an address at a hosting platform, where no DNS record can be added). The open-source inbox, to run on the business's own servers instead, is always named. After the owner adds the DNS record, check_dns says whether agents can reach the inbox.
Parameters:
domain(required) — string — The business's own domain, like salon.example (a URL is read as its domain).
Hints: read-only yes · destructive no · idempotent yes · open-world no
check_dnsread-onlyChecks whether AI agents are led from the business's website and DNS to its agent inbox, and whether the inbox answers at inbox.<domain> (or the host given): for a business's own AI. Reads the inbox's DNS record (against target, when given) and manifest, the site's robots.txt (no AI assistant kept out), and five ways the domain can point to the inbox: four on the website (/.well-known/agent-inbox.json, a line in llms.txt, <link rel="agent-inbox">, a schema.org potentialAction) and a _agent-inbox TXT record. ready needs one of the four on the website. Every item not in place comes with the exact record, line or file to add (fix_lines: the text to paste). Reads the site as a browser would, and nothing it asked crawlers not to read; what it read is kept for a minute.
Parameters:
domain(required) — string — The business's own domain, like salon.example (a URL is read as its domain).host— string — Where the inbox answers, when not inbox.<domain>: the domain itself or a name under it.target— string — The CNAME target the host must point to, when known (a hosted inbox's Connect page shows it).
Hints: read-only yes · destructive no · idempotent yes · open-world yes
Measured by MCPYP probing. Untested fields are omitted, never estimated. Listing is always free; MCPYP never proxies calls or stores user tokens.