unlob Docs
Browse documentation

web_search: search the index

Search the agent-first web index. Returns metadata-only hits (url, host, snippet, score, trust and graph signals) — never the page body; fetch that with get_document when a snippet is not enough.

Behaviour

The query supports boolean operators: AND, OR, -term to exclude, and "exact phrase". Name a vertical to disambiguate, or omit it and the router picks one from the query.

The index is admission-controlled, so a small result set usually means the index holds little on the topic, not that the query was wrong. One exception: if `partial` comes back true, part of the corpus was unreachable and the answer really is incomplete.

Every filter below is also a query parameter on GET /search, with the same name and the same meaning. IN-list filters accept either an array or a comma-separated string.

Costs 1 credit.

Arguments

inputSchema

NameTypeDescription
queryrequiredstringBoolean-capable: rust AND async, -python, "exact phrase"

Filters

The other 31 arguments are the filter set, which is not this tool's own. The same names and meanings are query parameters on GET /search, and what each one narrows is written out in Filters and sorting rather than a third time here. What is listed below is the part that differs over MCP: the JSON type each argument accepts, which is what you need to build the arguments object.

NameType
authorityarray | string
collapse"none" | "host" | "page" | "story"
communityarray | string
content_typearray | string
exclude_sitearray | string
facetsboolean
fieldsarray | string
frominteger
langstring
langsarray | string
limitinteger
max_wordsinteger
min_centralitynumber
min_host_ranknumber
min_independent_sourcesinteger
min_qualityinteger
min_wordsinteger
mode"keyword" | "semantic" | "hybrid"
prefer_authorityboolean
prefer_recentboolean
published_frominteger
published_tointeger
safeboolean
sitestring
sort"relevance" | "recency" | "host_rank" | "quality" | "published" | "words" | "centrality"
source"cc" | "delta"
termstring
tldarray | string
tointeger
topicarray | string
verticalstring

Argument shapes

The one argument that is not spelled the same on both transports is query, which is q as a query parameter. Every other name matches.

8 arguments take either a JSON array or a comma-separated string: authority, community, content_type, exclude_site, fields, langs, tld, topic. That is the one place the two transports differ in shape. A URL query string cannot carry an array, so the REST form of these is always the comma-separated one; an argument object can carry either.

Returns

A JSON payload in the text content block, and the same payload as structuredContent for clients that support it.

outputSchema

NameTypeDescription
facetsobjectPresent only when facets=true
moderequired"keyword" | "semantic" | "hybrid"The mode actually used
partialbooleantrue when at least one shard failed or timed out — the answer is short because a slice of the corpus was unreachable, NOT because that is all there is. Never treat a partial result as complete.
resultsrequiredobject[]—
routedrequiredbooleantrue when the router chose the vertical, false when you named it
totalrequiredinteger—
verticalstring | nullThe vertical actually queried

Calling it

Over Streamable HTTP, with the required arguments filled in:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "web_search",
    "arguments": {
      "query": "<query>"
    }
  }
}

Most clients do this for you — see Connect a client. To drive it by hand, complete the startup lifecycle first.

The same call over REST

If your client does not speak MCP, this capability is GET /search, taking the same parameters and returning the same body.

curl -H "x-api-key: $UNLOB_API_KEY" \
  "https://api.unlob.com/search?q=<query>"