Find services an agent can use, by what they do: remote MCP servers (with the tools each lists), local MCP servers (packages), pay-per-call APIs (x402, MPP), A2A agents and task marketplaces, with our checks for each. Search by words (query) or by capability tree node (branch); filter on type, access (none_asked, payment, credentials), max_price_usd and the evidence (passing, min_pass_rate); then call get_service for connection details. Results are compact; use limit/offset to page.
View input schema
{
"type": "object",
"properties": {
"scope": {
"description": "directory (default): services that meet the listing criteria (https://agentservicedirectory.com/methodology#directory); index: everything we watch.",
"type": "string",
"enum": [
"directory",
"index"
]
},
"branch": {
"description": "Capability tree id from get_tree, e.g. 'messaging/email/validation', 'places/weather' or 'places' (a node includes everything under it), or 'other'. Up to three ids separated by commas list services in any of them.",
"type": "string",
"maxLength": 250
},
"query": {
"description": "Text search (search/13) over names, hosts, URLs, operator names, the tool names an MCP server lists, and the name of a service's place in the capability tree when that place passed our placement checks. Write it as words or a sentence: words about payment or shape rather than purpose (mcp, api, pay, per, no, key, ..., and the words of a payment phrase such as \"pay per call\" or \"$0.01 a request\") are set aside and numbers left out (use the filters for those), and the response's query_words says which words were used. A service matches at least half the words (one of one or two). Services in a place the query names (by the place's name, description or the words agents use for it) rank first; then more matched words, then words found at the start of a word (send in 'Send Email' before send inside 'Godsend'), then the rarer words. A word of three or more characters matches the start of a word, or anywhere inside a name, host or operator word; one of seven or more also matches by its first five characters; a shorter word matches a whole word. Conditions read from the request (search/7): a fixed table turns phrases into conditions that rank, never filter. Pay per call, per request, x402, MPP, L402, USDC, no account or no signup: asks for payment. No API key, without a key, no auth, keyless, no sign-in: does not ask for credentials (observed or stated); \"an API key is fine\" lifts it. MCP: an MCP server (remote, hosted or endpoint: a remote one; local, install or package: a local one). A2A or agent card: an A2A agent. Under, below, at most $X, or a cent or less: a price per call at or below X. Fastest or low latency: faster first. For each service a condition is met by our observation, met by a statement (the operator's, a registry's, an OpenAPI description's), not known, or broken (observed or stated against it): services breaking fewer come first, then those meeting more, an observation counting twice a statement; one not known ranks below one met and above one broken. A condition in the same clause as preferably, ideally, if possible or would be nice is a preference: it orders only among services otherwise level. query_conditions in the response says which were read, from which words, and which are preferences; a filter given explicitly always wins. E.g. 'weather', or 'send an SMS, pay per call, no account'.",
"type": "string",
"maxLength": 300
},
"tag": {
"description": "Purpose tag, e.g. 'web-search'.",
"type": "string",
"maxLength": 32
},
"tier": {
"type": "string",
"enum": [
"reviewed",
"discovered"
]
},
"type": {
"type": "string",
"enum": [
"api_endpoint",
"task_marketplace",
"mcp_server",
"mcp_local",
"a2a_agent",
"web_api"
]
},
"network": {
"description": "Payment network, e.g. 'eip155:8453' (Base) or 'solana'.",
"type": "string",
"maxLength": 80
},
"passing": {
"description": "true: latest check passed.",
"type": "boolean"
},
"min_pass_rate": {
"description": "Share of checks passed in the last 30 days, 0 to 1.",
"type": "number",
"minimum": 0,
"maximum": 1
},
"min_checks": {
"description": "Minimum checks in the last 30 days, to avoid judging on one check.",
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"max_price_usd": {
"description": "Maximum price per call in USD stablecoin, where the price is known.",
"type": "number",
"minimum": 0
},
"max_terms_changes_90d": {
"description": "Only services whose observed x402 payment terms changed at most this many times in the last 90 days (0 = unchanged). Short histories are labelled limited.",
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"min_payers": {
"description": "Minimum unique payers in 30 days, as reported by the registry.",
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"max_median_ms": {
"description": "Over the last 30 days of our checks (response-times/1, measured from eastern North America; one operation per service, timeouts counted at the time limit); services with too few checks for the figure are left out. Maximum median response time in milliseconds.",
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"max_p95_ms": {
"description": "Over the last 30 days of our checks (response-times/1, measured from eastern North America; one operation per service, timeouts counted at the time limit); services with too few checks for the figure are left out. Maximum 95th-percentile response time in milliseconds.",
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"access": {
"description": "What the service asks of a caller (access/1): 'payment' (our plain request got HTTP 402), 'credentials' (HTTP 401, or its agent card or MCP Registry entry says so) or 'none_asked' (answered without asking for either, and nothing stated says credentials are needed). Services with no value are left out.",
"type": "string",
"enum": [
"payment",
"credentials",
"none_asked"
]
},
"payment_model": {
"description": "'per_call': it asked for payment for our request (HTTP 402). Services whose payment model is not known are left out.",
"type": "string",
"enum": [
"per_call"
]
},
"currency": {
"description": "ISO 4217 code (USD so far): services whose payment terms, seen in their own HTTP 402 answers to our checks, are in this currency; a stablecoin counts as the currency it tracks (USDC as USD). Services whose currency we have not observed are left out.",
"type": "string",
"maxLength": 3
},
"covers": {
"description": "A country (ISO 3166-1 alpha-2, e.g. AT) the service's own text says its data or job is about; a service that states a region including it (EU, Europe) or worldwide matches too. Comma-separated values are alternatives. Strict: services whose own text states nothing on this are left out (stated-facts/5).",
"type": "string",
"maxLength": 80
},
"processed_in": {
"description": "A country (ISO 3166-1 alpha-2) where the service's own text says it processes or stores data; a stated region including it or worldwide matches too. Comma-separated values are alternatives. Strict: services whose own text states nothing on this are left out (stated-facts/5).",
"type": "string",
"maxLength": 80
},
"acts": {
"description": "What the service's own text says it does in the world when called: read_only, or what it changes. Values: read_only, sends_messages, spends_money, books_or_orders, writes_data, deletes_data, posts_publicly, controls_devices. Comma-separated values are alternatives. Strict: services whose own text states nothing on this are left out (stated-facts/5). Not shown yet: this kind has not passed our checks, so the filter matches no service for now.",
"type": "string",
"maxLength": 80
},
"audience": {
"description": "Who the service's own text says it is for. Values: consumers, businesses, developers, agents. Comma-separated values are alternatives. Strict: services whose own text states nothing on this are left out (stated-facts/5).",
"type": "string",
"maxLength": 80
},
"format": {
"description": "A format the service's own text names for what it returns. Values: json, csv, xml, pdf, html, text, markdown, image, audio, video, geojson. Comma-separated values are alternatives. Strict: services whose own text states nothing on this are left out (stated-facts/5). Not shown yet: this kind has not passed our checks, so the filter matches no service for now.",
"type": "string",
"maxLength": 80
},
"delivery": {
"description": "How the service's own text says results come back. Values: sync, async, webhook, streaming, batch. Comma-separated values are alternatives. Strict: services whose own text states nothing on this are left out (stated-facts/5). Not shown yet: this kind has not passed our checks, so the filter matches no service for now.",
"type": "string",
"maxLength": 80
},
"freshness": {
"description": "How current the service's own text says its data is. Values: live, hourly, daily, weekly, periodic, static. Comma-separated values are alternatives. Strict: services whose own text states nothing on this are left out (stated-facts/5). Not shown yet: this kind has not passed our checks, so the filter matches no service for now.",
"type": "string",
"maxLength": 80
},
"data_stored": {
"description": "Whether the service's own text says it keeps or logs what callers send. Values: true, false. Comma-separated values are alternatives. Strict: services whose own text states nothing on this are left out (stated-facts/5). Not shown yet: this kind has not passed our checks, so the filter matches no service for now.",
"type": "string",
"maxLength": 80
},
"language": {
"description": "A language (ISO 639-1, e.g. de) the service's own text says its content or output is in. Comma-separated values are alternatives. Strict: services whose own text states nothing on this are left out (stated-facts/5). Not shown yet: this kind has not passed our checks, so the filter matches no service for now.",
"type": "string",
"maxLength": 80
},
"payment_method": {
"description": "A way to pay the service's own text names. Payment protocols (x402, MPP, L402) are observed from payment requests: see access.observed. Values: card, bank, invoice, crypto, stablecoin, paypal. Comma-separated values are alternatives. Strict: services whose own text states nothing on this are left out (stated-facts/5). Not shown yet: this kind has not passed our checks, so the filter matches no service for now.",
"type": "string",
"maxLength": 80
},
"provider": {
"description": "Only endpoints from this provider (registrable domain, e.g. 'example.com'), as given in a result's provider field.",
"type": "string",
"maxLength": 253
},
"one_per_provider": {
"description": "Return one endpoint per provider (registrable domain): the first under the chosen sort (by default, the evidence order: the share of checks passed, then how long we have watched it).",
"type": "boolean"
},
"sort": {
"description": "Default: relevance when query is given, otherwise evidence. relevance (the default when q is given): first services in a place the query names (search/5, by the place's name, description or the words agents use for it; search/11: found without the request's payment, key, price and speed wording, such as \"pay per call with USDC\", unless nothing else names a place; search/12: of places named by the same words in another order, such as speech to text and text to speech, the one whose name the request has in order), and among them those breaking fewer of the conditions read from the request, then, when no covers filter names a place, those whose own text does not limit them to particular places (search/10: a stated country or region and not worldwide comes later; nothing is hidden), then those meeting more conditions (search/7: pay per call, no API key, MCP, a price limit; an observation counts twice a statement; see query_conditions), then the better-matched place, then services matching more of the query's words (and, among those matching as many, the rarer words), then those meeting more of the preferences read, then those whose provider's domain starts with the first word used (its own site: q=stripe puts stripe.com first), then those whose name is, starts with or contains the words used, then the rest; within each group, the evidence order (evidence/2). evidence (evidence/2, the default without q): first services with at least 5 checks in 30 days, then by the share of those checks passed, then by how long we have watched them (longest first), then by payers as the registry reports them, as a tiebreak only. provider-mix/1: in every sort but name and recent, each provider's results after its first three come after every other provider's first three, so one provider cannot fill a page; provider= (or host=) lists one provider's services in plain order, and group=provider gives one per provider. median_ms and p95_ms: fastest first over 30 days, services without the figure last.",
"type": "string",
"enum": [
"relevance",
"evidence",
"pass_rate",
"payers",
"price",
"median_ms",
"p95_ms",
"recent",
"name"
]
},
"limit": {
"description": "Default 10, maximum 25.",
"type": "integer",
"minimum": 1,
"maximum": 25
},
"offset": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
}
},
"$schema": "https://json-schema.org/draft/2020-12/schema"
}