Find businesses an AI agent can message, book or buy from, and check what an agent can do on a site.
Maintain this server? Claim it
Call this server's tools from your browser. Nothing to install.
Requests go through mcptry because browsers can't call most MCP servers directly. Header values are sent to the server for that request only and are never stored or logged.
Tool list from our last check. Connect live to refresh it.
Sends 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.
The business's domain, as search_businesses or get_business gave it, like bikes.example.
true only when your person agreed to give this business their email address for its answer. Without it nothing is sent.
Where the business can answer. Only an email address and a name: never a phone number.
What your person wants to ask, in their words.
A few words the business sees first.
The language your person wants the answer in, as a tag like en, pt or pt-BR.
This tool isn't marked read-only, so it may change something on the server or in an account you connected.
Sends 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.
| Argument | Type | Description |
|---|---|---|
| domain* | string | The business's domain, as search_businesses or get_business gave it, like bikes.example. |
| consent* | boolean | true only when your person agreed to give this business their email address for its answer. Without it nothing is sent. |
| contact* | object | Where the business can answer. Only an email address and a name: never a phone number. |
| message* | string | What your person wants to ask, in their words. |
| 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. |
{
"type": "object",
"title": "MCP ask_business: arguments",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"domain",
"message",
"contact",
"consent"
],
"properties": {
"domain": {
"type": "string",
"maxLength": 253,
"minLength": 1,
"description": "The business's domain, as search_businesses or get_business gave it, like bikes.example."
},
"consent": {
"type": "boolean",
"const": true,
"description": "true only when your person agreed to give this business their email address for its answer. Without it nothing is sent."
},
"contact": {
"type": "object",
"required": [
"email"
],
"properties": {
"name": {
"type": "string",
"maxLength": 100,
"minLength": 1,
"description": "The name your person wants the business to use."
},
"email": {
"type": "string",
"pattern": "^[^\\s@<>()\\[\\],;:\"]{1,64}@[^\\s@<>()\\[\\],;:\"]+\\.[^\\s@<>()\\[\\],;:\"]{2,}$",
"maxLength": 254,
"description": "Your person's email address, which they agreed to give this business for its answer."
}
},
"description": "Where the business can answer. Only an email address and a name: never a phone number.",
"additionalProperties": false
},
"message": {
"type": "string",
"maxLength": 4000,
"minLength": 1,
"description": "What your person wants to ask, in their words."
},
"subject": {
"type": "string",
"maxLength": 150,
"minLength": 1,
"description": "A few words the business sees first."
},
"language": {
"type": "string",
"pattern": "^[A-Za-z]{2,3}(-[A-Za-z0-9]{2,8})*$",
"maxLength": 12,
"description": "The language your person wants the answer in, as a tag like en, pt or pt-BR."
}
}
}Checks 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/.
| Argument | Type | Description |
|---|---|---|
| url* | 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. |
{
"type": "object",
"title": "MCP check_business: arguments",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"url"
],
"properties": {
"url": {
"type": "string",
"maxLength": 2048,
"minLength": 1,
"description": "The business's website, as a URL or a bare domain like salon.example."
},
"fresh": {
"type": "boolean",
"default": false,
"description": "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."
}
}
}Checks 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.
| Argument | Type | Description |
|---|---|---|
| host | string | Where the inbox answers, when not inbox.<domain>: the domain itself or a name under it. |
| domain* | string | The business's own domain, like salon.example (a URL is read as its domain). |
| target | string | The CNAME target the host must point to, when known (a hosted inbox's Connect page shows it). |
{
"type": "object",
"title": "MCP check_dns: arguments",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"domain"
],
"properties": {
"host": {
"type": "string",
"maxLength": 253,
"description": "Where the inbox answers, when not inbox.<domain>: the domain itself or a name under it."
},
"domain": {
"type": "string",
"maxLength": 253,
"minLength": 1,
"description": "The business's own domain, like salon.example (a URL is read as its domain)."
},
"target": {
"type": "string",
"maxLength": 253,
"description": "The CNAME target the host must point to, when known (a hosted inbox's Connect page shows it)."
}
}
}One 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/.
| Argument | Type | Description |
|---|---|---|
| domain* | string | The business's domain, like ana-salon.example, as search_businesses gave it. |
{
"type": "object",
"title": "MCP get_business: arguments",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"domain"
],
"properties": {
"domain": {
"type": "string",
"maxLength": 253,
"minLength": 1,
"description": "The business's domain, like ana-salon.example, as search_businesses gave it."
}
}
}Monthly 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/.
| Argument | Type | Description |
|---|---|---|
| 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. |
{
"type": "object",
"title": "MCP get_census: arguments",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"key": {
"type": "string",
"maxLength": 64,
"description": "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": {
"type": "string",
"pattern": "^[a-z][a-z0-9_]{0,31}$",
"description": "all (the default), country, group (kind of business), platform, source (where the sites came from) or city."
},
"edition": {
"type": "string",
"pattern": "^20\\d\\d-(0[1-9]|1[0-2])$",
"description": "The month, YYYY-MM. Without it, the latest published edition."
}
}
}The 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.
No arguments.
{
"type": "object",
"title": "MCP list_attributes: arguments",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {}
}The 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.
No arguments.
{
"type": "object",
"title": "MCP list_categories: arguments",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {}
}For 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.
| Argument | Type | Description |
|---|---|---|
| pay | array | Payment tokens of list_attributes. |
| name* | string | As the business writes it. |
| agree* | boolean | The business agrees to be listed by the network's published rules (GET /v1/ranking) and listing terms. |
| doors | array | |
| hours | object | As a profile's hours: {"timezone": "Europe/Paris", "weekly": {"tue": [["09:00", "19:00"]]}}. |
Records 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).
| Argument | Type | Description |
|---|---|---|
| v* | number | |
| reports* | array |
{
"type": "object",
"title": "MCP report_door: arguments",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"v",
"reports"
],
"properties": {
"v": {
"type": "number",
"const": 1
},
"reports": {
"type": "array",
"items": {
"type": "object",
"required": [
"domain",
"door",
"op",
"at",
"intent",
"result"
],
"properties": {
"at": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "When, in Unix seconds; the network keeps it to the minute."
},
"ms": {
"type": "integer",
"maximum": 600000,
"minimum": 0,
"description": "How long the door took to answer, in milliseconds."
},
"op": {
"type": "string",
"pattern": "^[a-z][a-z0-9_]{0,31}$",
"description": "What was attempted, from the capability vocabulary (vocab/capabilities.json): book, order, message, …"
},
"door": {
"type": "object",
"required": [
"type",
"url"
],
"properties": {
"url": {
"type": "string",
"maxLength": 2048,
"minLength": 1,
"description": "The door's URL exactly as the network shows it; for an inbox, the address used: inbox.url, inbox.mcp or inbox.rest."
},
"type": {
"type": "string",
"pattern": "^[a-z0-9:_-]{1,48}$",
"description": "The door's type as the network shows it: inbox for a member's inbox; mcp, a2a, openapi, api, … or platform:<name>."
}
},
"additionalProperties": false
},
"tool": {
"type": "string",
"pattern": "^[a-z0-9_.-]{1,64}$",
"description": "The tool or operation called at the door, in lowercase."
},
"class": {
"type": "string",
"pattern": "^[a-z0-9_.]{1,64}$",
"description": "Why, from vocab/door-report-classes.json: required unless the result is ok, and absent when it is."
},
"token": {
"type": "string",
"pattern": "^[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+$",
"maxLength": 1024,
"description": "The door's signed outcome token from its answer, when it gave one, as it came."
},
"domain": {
"type": "string",
"pattern": "^[a-z0-9.-]{1,253}$",
"description": "The business's domain, as the network lists it."
},
"intent": {
"type": "string",
"pattern": "^[A-Za-z0-9_-]{8,32}$",
"description": "8 to 32 base64url characters, one per attempt with all its retries: an attempt counts once."
},
"result": {
"enum": [
"ok",
"refused",
"invalid",
"fail",
"info"
],
"type": "string"
}
},
"additionalProperties": false
},
"maxItems": 100,
"minItems": 1
}
},
"additionalProperties": false
}Without 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.
| Argument | Type | Description |
|---|---|---|
| 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. |
| domain* | string | The business's domain, as search_businesses or get_business gave it, like bikes.example. |
| 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. |
| service* | string |
Asks 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.
| Argument | Type | Description |
|---|---|---|
| what* | string | What the quote is for, in a few words: Wheel rebuild, Kitchen tiling. |
| domain* | string | The business's domain, as search_businesses or get_business gave it, like bikes.example. |
| consent* | boolean | true only when your person agreed to give this business their email address for its answer. Without it nothing is sent. |
| contact* | object | Where the business can answer. Only an email address and a name: never a phone number. |
| details* | string | What the business needs to know to give a price. |
| language | string | The language your person wants the answer in, as a tag like en, pt or pt-BR. |
| quantity |
Find 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.
| Argument | Type | Description |
|---|---|---|
| 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. |
For 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.
| Argument | Type | Description |
|---|---|---|
| domain* | string | The business's own domain, like salon.example (a URL is read as its domain). |
{
"type": "object",
"title": "MCP start_inbox: arguments",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"domain"
],
"properties": {
"domain": {
"type": "string",
"maxLength": 253,
"minLength": 1,
"description": "The business's own domain, like salon.example (a URL is read as its domain)."
}
}
}For 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.
| Argument | Type | Description |
|---|---|---|
| set | object | Any field register_business takes, but domain. |
| doors | object | |
| proof | object | |
| domain* | string | |
| listing | 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. |
| proof | object |
| where* | object | A storefront needs an address or geo, a service area its radius or countries, online its ships_to. |
| domain* | string | The business's own website domain. A business without a website is not supported yet. |
| locale | string | The language to answer in. |
| category* | object | What the business is: one category, and at most two more. |
| languages* | array | Language tags, like pt or fr-CA. |
| attributes | object | Keys of list_attributes. |
| currencies | array | ISO 4217. |
| price_band | integer | 1 (cheapest) to 4. |
| want_inbox | boolean |
| claim_token | string | Given by a successful register_business: proof again for 90 days, for this listing only. |
| description* | string | One line on what it does; the first line is at most 160. |
| 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). |
{
"type": "object",
"title": "MCP register_business: arguments",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"domain",
"name",
"category",
"description",
"where",
"languages",
"agree"
],
"properties": {
"pay": {
"type": "array",
"items": {
"type": "string",
"maxLength": 40
},
"maxItems": 30,
"description": "Payment tokens of list_attributes."
},
"name": {
"type": "string",
"maxLength": 200,
"minLength": 1,
"description": "As the business writes it."
},
"agree": {
"type": "boolean",
"const": true,
"description": "The business agrees to be listed by the network's published rules (GET /v1/ranking) and listing terms."
},
"doors": {
"type": "array",
"items": {
"type": "object",
"required": [
"type",
"url"
],
"properties": {
"url": {
"type": "string",
"maxLength": 2048,
"description": "https, with no user in it."
},
"type": {
"type": "string",
"maxLength": 60,
"description": "inbox, mcp, a2a, openapi, api, ucp, acp, nlweb, webhook, other, or platform:<name>. Mail, phone, messaging, forms and web pages are human channels and never doors."
},
"kinds": {
"type": "array",
"items": {
"type": "string",
"maxLength": 20
},
"maxItems": 4,
"description": "Of ask, quote, book, order: what it answers."
},
"protocol": {
"type": "string",
"maxLength": 40,
"description": "What it speaks, for type \"other\": like beckn or graphql."
},
"terms_url": {
"type": "string",
"maxLength": 2048
},
"rate_limit": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Requests a day this door takes, 1 to 20; it only lowers the network's own."
}
}
},
"maxItems": 10
},
"hours": {
"type": "object",
"required": [
"timezone",
"weekly"
],
"properties": {
"weekly": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"type": "array",
"items": {
"type": "array",
"items": {
"type": "string",
"maxLength": 5
}
}
}
},
"closures": {
"type": "array",
"items": {
"type": "object",
"required": [
"from",
"to"
],
"properties": {
"to": {
"type": "string",
"maxLength": 10
},
"from": {
"type": "string",
"maxLength": 10
}
}
},
"maxItems": 100
},
"timezone": {
"type": "string",
"maxLength": 64
}
},
"description": "As a profile's hours: {\"timezone\": \"Europe/Paris\", \"weekly\": {\"tue\": [[\"09:00\", \"19:00\"]]}}."
},
"proof": {
"type": "object",
"required": [
"method"
],
"properties": {
"kid": {
"type": "string",
"maxLength": 200,
"description": "key: the key that signed."
},
"code": {
"type": "string",
"pattern": "^[0-9]{8}$",
"description": "code: the 8 digits sent to that address."
},
"email": {
"type": "string",
"maxLength": 254,
"description": "code: an address at exactly the business's own domain (not a subdomain), typed by the owner; never a public mail or internet provider's domain."
},
"method": {
"enum": [
"well_known",
"manifest",
"dns",
"key",
"code"
],
"type": "string"
},
"signature": {
"type": "string",
"maxLength": 1024,
"description": "key: base64url of the signature."
},
"challenge_id": {
"type": "string",
"maxLength": 64
}
}
},
"where": {
"type": "object",
"required": [
"kind"
],
"properties": {
"geo": {
"type": "object",
"required": [
"lat",
"lng"
],
"properties": {
"lat": {
"type": "number",
"maximum": 90,
"minimum": -90
},
"lng": {
"type": "number",
"maximum": 180,
"minimum": -180
}
}
},
"kind": {
"type": "array",
"items": {
"enum": [
"storefront",
"service_area",
"online"
],
"type": "string"
},
"minItems": 1
},
"address": {
"type": "object",
"properties": {
"region": {
"type": "string",
"maxLength": 100
},
"street": {
"type": "string",
"maxLength": 200
},
"country": {
"type": "string",
"maxLength": 2
},
"locality": {
"type": "string",
"maxLength": 100
},
"postal_code": {
"type": "string",
"maxLength": 20
}
}
},
"ships_to": {
"type": "array",
"items": {
"type": "string",
"maxLength": 2
},
"maxItems": 250
},
"service_area": {
"type": "object",
"properties": {
"countries": {
"type": "array",
"items": {
"type": "string",
"maxLength": 2
},
"description": "At most 50."
},
"radius_km": {
"type": "number",
"description": "At most 300."
}
}
}
},
"description": "A storefront needs an address or geo, a service area its radius or countries, online its ships_to."
},
"domain": {
"type": "string",
"maxLength": 253,
"minLength": 1,
"description": "The business's own website domain. A business without a website is not supported yet."
},
"locale": {
"type": "string",
"maxLength": 35,
"description": "The language to answer in."
},
"category": {
"type": "object",
"required": [
"primary"
],
"properties": {
"primary": {
"type": "string",
"maxLength": 80,
"description": "A place category id (GET /v1/categories?group=…) or a group slug."
},
"alternates": {
"type": "array",
"items": {
"type": "string",
"maxLength": 80
},
"maxItems": 2
}
},
"description": "What the business is: one category, and at most two more."
},
"languages": {
"type": "array",
"items": {
"type": "string",
"maxLength": 35
},
"maxItems": 10,
"minItems": 1,
"description": "Language tags, like pt or fr-CA."
},
"attributes": {
"type": "object",
"description": "Keys of list_attributes.",
"propertyNames": {
"type": "string",
"maxLength": 60
},
"additionalProperties": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "string",
"maxLength": 60
}
]
}
},
"currencies": {
"type": "array",
"items": {
"type": "string",
"maxLength": 3
},
"maxItems": 5,
"description": "ISO 4217."
},
"price_band": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "1 (cheapest) to 4."
},
"want_inbox": {
"type": "boolean"
},
"claim_token": {
"type": "string",
"pattern": "^sdc_[A-Za-z0-9_-]{43}$",
"description": "Given by a successful register_business: proof again for 90 days, for this listing only."
},
"description": {
"type": "string",
"maxLength": 500,
"minLength": 1,
"description": "One line on what it does; the first line is at most 160."
},
"alternate_names": {
"type": "array",
"items": {
"type": "string",
"maxLength": 200
},
"maxItems": 5,
"description": "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)."
}
}
}| The service's name, as get_business lists it, or its id from this tool's 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. |
{
"type": "object",
"title": "MCP request_booking: arguments",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"domain",
"service"
],
"properties": {
"from": {
"type": "string",
"format": "date",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
"description": "Without start: the first day to show free times for (today when left out)."
},
"notes": {
"type": "string",
"maxLength": 2000,
"minLength": 1,
"description": "Anything the business should know."
},
"start": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
"description": "When your person wants it to start, from this tool's free times. Leave it out to see them first."
},
"domain": {
"type": "string",
"maxLength": 253,
"minLength": 1,
"description": "The business's domain, as search_businesses or get_business gave it, like bikes.example."
},
"consent": {
"type": "boolean",
"const": true,
"description": "Needed with start: true only when your person agreed to give this business their email address."
},
"contact": {
"type": "object",
"required": [
"email"
],
"properties": {
"name": {
"type": "string",
"maxLength": 100,
"minLength": 1,
"description": "The name your person wants the business to use."
},
"email": {
"type": "string",
"pattern": "^[^\\s@<>()\\[\\],;:\"]{1,64}@[^\\s@<>()\\[\\],;:\"]+\\.[^\\s@<>()\\[\\],;:\"]{2,}$",
"maxLength": 254,
"description": "Your person's email address, which they agreed to give this business for its answer."
}
},
"description": "Needed with start: where the business can answer.",
"additionalProperties": false
},
"service": {
"type": "string",
"maxLength": 200,
"minLength": 1,
"description": "The service's name, as get_business lists it, or its id from this tool's answer."
},
"language": {
"type": "string",
"pattern": "^[A-Za-z]{2,3}(-[A-Za-z0-9]{2,8})*$",
"maxLength": 12,
"description": "The language your person wants the answer in, as a tag like en, pt or pt-BR."
},
"terms_sha": {
"type": "string",
"pattern": "^[A-Za-z0-9_-]{43}$",
"description": "The confirm.terms_sha of the last answer, sent only after your person said yes to its summary."
},
"party_size": {
"type": "integer",
"maximum": 50,
"minimum": 1,
"description": "How many people it is for, when that matters."
}
}
}| integer |
| How many, when it is a number of things. |
| needed_by | string | The date your person needs it by, as YYYY-MM-DD. |
{
"type": "object",
"title": "MCP request_quote: arguments",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"domain",
"what",
"details",
"contact",
"consent"
],
"properties": {
"what": {
"type": "string",
"maxLength": 200,
"minLength": 1,
"description": "What the quote is for, in a few words: Wheel rebuild, Kitchen tiling."
},
"domain": {
"type": "string",
"maxLength": 253,
"minLength": 1,
"description": "The business's domain, as search_businesses or get_business gave it, like bikes.example."
},
"consent": {
"type": "boolean",
"const": true,
"description": "true only when your person agreed to give this business their email address for its answer. Without it nothing is sent."
},
"contact": {
"type": "object",
"required": [
"email"
],
"properties": {
"name": {
"type": "string",
"maxLength": 100,
"minLength": 1,
"description": "The name your person wants the business to use."
},
"email": {
"type": "string",
"pattern": "^[^\\s@<>()\\[\\],;:\"]{1,64}@[^\\s@<>()\\[\\],;:\"]+\\.[^\\s@<>()\\[\\],;:\"]{2,}$",
"maxLength": 254,
"description": "Your person's email address, which they agreed to give this business for its answer."
}
},
"description": "Where the business can answer. Only an email address and a name: never a phone number.",
"additionalProperties": false
},
"details": {
"type": "string",
"maxLength": 4000,
"minLength": 1,
"description": "What the business needs to know to give a price."
},
"language": {
"type": "string",
"pattern": "^[A-Za-z]{2,3}(-[A-Za-z0-9]{2,8})*$",
"maxLength": 12,
"description": "The language your person wants the answer in, as a tag like en, pt or pt-BR."
},
"quantity": {
"type": "integer",
"maximum": 100000,
"minimum": 1,
"description": "How many, when it is a number of things."
},
"needed_by": {
"type": "string",
"format": "date",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
"description": "The date your person needs it by, as YYYY-MM-DD."
}
}
}| 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. |
{
"type": "object",
"title": "MCP search_businesses: arguments",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"near": {
"type": "object",
"required": [
"lat",
"lng"
],
"properties": {
"lat": {
"type": "number",
"maximum": 90,
"minimum": -90
},
"lng": {
"type": "number",
"maximum": 180,
"minimum": -180
},
"radius_km": {
"type": "number",
"maximum": 1000,
"description": "How far from the point, in kilometres: 10 when left out.",
"exclusiveMinimum": 0
}
},
"description": "Only businesses within radius_km of this point, each with its distance."
},
"level": {
"enum": [
"listed",
"readable",
"askable",
"bookable",
"orderable",
"payable"
],
"type": "string",
"description": "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": {
"type": "integer",
"maximum": 20,
"minimum": 1,
"description": "How many to return: 10 when left out."
},
"order": {
"enum": [
"rank",
"nearest"
],
"type": "string",
"description": "rank: the published order (the default); nearest: by distance, and it needs near."
},
"query": {
"type": "string",
"maxLength": 80,
"description": "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": {
"type": "string",
"maxLength": 512,
"description": "next_cursor from the previous answer, for the next page of the same search."
},
"source": {
"type": "array",
"items": {
"enum": [
"member",
"registered",
"found"
],
"type": "string"
},
"maxItems": 3,
"description": "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": {
"type": "array",
"items": {
"type": "string",
"maxLength": 40
},
"maxItems": 8,
"description": "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": {
"type": "string",
"pattern": "^[A-Za-z]{2}$",
"description": "A country code like PT or BR: a business located there, serving it or shipping there. This only leaves businesses out."
},
"category": {
"type": "string",
"maxLength": 60,
"description": "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": {
"type": "string",
"pattern": "^[A-Za-z]{2,3}(-[A-Za-z0-9]{2,8})*$",
"maxLength": 12,
"description": "Only businesses that speak this language, as a tag like pt or en; pt also finds pt-br."
},
"open_now": {
"type": "boolean",
"description": "true: only businesses open right now by the hours they published. One that published no hours is left out."
},
"door_type": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string",
"pattern": "^(inbox|mcp|a2a|openapi|api|ucp|acp|nlweb|webhook|other|platform:[a-z0-9-]{1,40})$"
},
{
"type": "string",
"const": "platform"
}
]
},
"maxItems": 5,
"description": "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": {
"type": "boolean",
"description": "true: with an inbox door; false: without one. This only leaves businesses out."
},
"item_type": {
"enum": [
"booking",
"order",
"quote_request",
"message"
],
"type": "string",
"description": "Only businesses whose inbox takes this."
},
"attributes": {
"type": "array",
"items": {
"type": "string",
"maxLength": 60
},
"maxItems": 10,
"description": "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": {
"type": "string",
"pattern": "^[1-4](-[1-4])?$",
"description": "1 (cheapest) to 4, as \"2\" or a range \"1-2\". This only leaves businesses out."
},
"requestable": {
"enum": [
"ask",
"quote"
],
"type": "string",
"description": "A live door that declared it answers this kind. This only leaves businesses out."
}
}
}| claim_token | string | Given by a successful register_business: proof again for 90 days, for this listing only. |
{
"type": "object",
"title": "MCP update_business: arguments",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"domain"
],
"properties": {
"set": {
"type": "object",
"properties": {
"pay": {
"type": "array",
"items": {
"type": "string",
"maxLength": 40
},
"maxItems": 30,
"description": "Payment tokens of list_attributes."
},
"name": {
"type": "string",
"maxLength": 200,
"minLength": 1,
"description": "As the business writes it."
},
"doors": {
"type": "array",
"items": {
"type": "object",
"required": [
"type",
"url"
],
"properties": {
"url": {
"type": "string",
"maxLength": 2048,
"description": "https, with no user in it."
},
"type": {
"type": "string",
"maxLength": 60,
"description": "inbox, mcp, a2a, openapi, api, ucp, acp, nlweb, webhook, other, or platform:<name>. Mail, phone, messaging, forms and web pages are human channels and never doors."
},
"kinds": {
"type": "array",
"items": {
"type": "string",
"maxLength": 20
},
"maxItems": 4,
"description": "Of ask, quote, book, order: what it answers."
},
"protocol": {
"type": "string",
"maxLength": 40,
"description": "What it speaks, for type \"other\": like beckn or graphql."
},
"terms_url": {
"type": "string",
"maxLength": 2048
},
"rate_limit": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Requests a day this door takes, 1 to 20; it only lowers the network's own."
}
}
},
"maxItems": 10
},
"hours": {
"type": "object",
"required": [
"timezone",
"weekly"
],
"properties": {
"weekly": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"type": "array",
"items": {
"type": "array",
"items": {
"type": "string",
"maxLength": 5
}
}
}
},
"closures": {
"type": "array",
"items": {
"type": "object",
"required": [
"from",
"to"
],
"properties": {
"to": {
"type": "string",
"maxLength": 10
},
"from": {
"type": "string",
"maxLength": 10
}
}
},
"maxItems": 100
},
"timezone": {
"type": "string",
"maxLength": 64
}
},
"description": "As a profile's hours: {\"timezone\": \"Europe/Paris\", \"weekly\": {\"tue\": [[\"09:00\", \"19:00\"]]}}."
},
"where": {
"type": "object",
"required": [
"kind"
],
"properties": {
"geo": {
"type": "object",
"required": [
"lat",
"lng"
],
"properties": {
"lat": {
"type": "number",
"maximum": 90,
"minimum": -90
},
"lng": {
"type": "number",
"maximum": 180,
"minimum": -180
}
}
},
"kind": {
"type": "array",
"items": {
"enum": [
"storefront",
"service_area",
"online"
],
"type": "string"
},
"minItems": 1
},
"address": {
"type": "object",
"properties": {
"region": {
"type": "string",
"maxLength": 100
},
"street": {
"type": "string",
"maxLength": 200
},
"country": {
"type": "string",
"maxLength": 2
},
"locality": {
"type": "string",
"maxLength": 100
},
"postal_code": {
"type": "string",
"maxLength": 20
}
}
},
"ships_to": {
"type": "array",
"items": {
"type": "string",
"maxLength": 2
},
"maxItems": 250
},
"service_area": {
"type": "object",
"properties": {
"countries": {
"type": "array",
"items": {
"type": "string",
"maxLength": 2
},
"description": "At most 50."
},
"radius_km": {
"type": "number",
"description": "At most 300."
}
}
}
},
"description": "A storefront needs an address or geo, a service area its radius or countries, online its ships_to."
},
"locale": {
"type": "string",
"maxLength": 35,
"description": "The language to answer in."
},
"category": {
"type": "object",
"required": [
"primary"
],
"properties": {
"primary": {
"type": "string",
"maxLength": 80,
"description": "A place category id (GET /v1/categories?group=…) or a group slug."
},
"alternates": {
"type": "array",
"items": {
"type": "string",
"maxLength": 80
},
"maxItems": 2
}
},
"description": "What the business is: one category, and at most two more."
},
"languages": {
"type": "array",
"items": {
"type": "string",
"maxLength": 35
},
"maxItems": 10,
"minItems": 1,
"description": "Language tags, like pt or fr-CA."
},
"attributes": {
"type": "object",
"description": "Keys of list_attributes.",
"propertyNames": {
"type": "string",
"maxLength": 60
},
"additionalProperties": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "string",
"maxLength": 60
}
]
}
},
"currencies": {
"type": "array",
"items": {
"type": "string",
"maxLength": 3
},
"maxItems": 5,
"description": "ISO 4217."
},
"price_band": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "1 (cheapest) to 4."
},
"want_inbox": {
"type": "boolean"
},
"description": {
"type": "string",
"maxLength": 500,
"minLength": 1,
"description": "One line on what it does; the first line is at most 160."
},
"alternate_names": {
"type": "array",
"items": {
"type": "string",
"maxLength": 200
},
"maxItems": 5,
"description": "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)."
}
},
"description": "Any field register_business takes, but domain."
},
"doors": {
"type": "object",
"properties": {
"add": {
"type": "array",
"items": {
"type": "object",
"required": [
"type",
"url"
],
"properties": {
"url": {
"type": "string",
"maxLength": 2048,
"description": "https, with no user in it."
},
"type": {
"type": "string",
"maxLength": 60,
"description": "inbox, mcp, a2a, openapi, api, ucp, acp, nlweb, webhook, other, or platform:<name>. Mail, phone, messaging, forms and web pages are human channels and never doors."
},
"kinds": {
"type": "array",
"items": {
"type": "string",
"maxLength": 20
},
"maxItems": 4,
"description": "Of ask, quote, book, order: what it answers."
},
"protocol": {
"type": "string",
"maxLength": 40,
"description": "What it speaks, for type \"other\": like beckn or graphql."
},
"terms_url": {
"type": "string",
"maxLength": 2048
},
"rate_limit": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Requests a day this door takes, 1 to 20; it only lowers the network's own."
}
}
},
"maxItems": 10
},
"remove": {
"type": "array",
"items": {
"type": "string",
"maxLength": 2048
},
"maxItems": 10,
"description": "Door URLs."
}
}
},
"proof": {
"type": "object",
"required": [
"method"
],
"properties": {
"kid": {
"type": "string",
"maxLength": 200,
"description": "key: the key that signed."
},
"code": {
"type": "string",
"pattern": "^[0-9]{8}$",
"description": "code: the 8 digits sent to that address."
},
"email": {
"type": "string",
"maxLength": 254,
"description": "code: an address at exactly the business's own domain (not a subdomain), typed by the owner; never a public mail or internet provider's domain."
},
"method": {
"enum": [
"well_known",
"manifest",
"dns",
"key",
"code"
],
"type": "string"
},
"signature": {
"type": "string",
"maxLength": 1024,
"description": "key: base64url of the signature."
},
"challenge_id": {
"type": "string",
"maxLength": 64
}
}
},
"domain": {
"type": "string",
"maxLength": 253,
"minLength": 1
},
"listing": {
"enum": [
"on",
"off"
],
"type": "string",
"description": "off hides it from search and keeps it in the index."
},
"opt_out": {
"type": "object",
"required": [
"scopes"
],
"properties": {
"scopes": {
"type": "array",
"items": {
"enum": [
"list",
"crawl",
"all"
],
"type": "string"
},
"maxItems": 3,
"minItems": 1
}
},
"description": "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": {
"enum": [
"hidden",
"shown"
],
"type": "string",
"description": "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": {
"type": "string",
"pattern": "^sdc_[A-Za-z0-9_-]{43}$",
"description": "Given by a successful register_business: proof again for 90 days, for this listing only."
}
}
}