Skip to content

web_search: Serply as an API key service - #6

Merged
1ay1 merged 2 commits into
agentty-org:masterfrom
googio:feat/serply-search
Oct 17, 2026
Merged

1ay1 merged 2 commits into
agentty-org:masterfrom
googio:feat/serply-search

Conversation

@googio

@googio googio commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

web_search: Serply as an API key service

Adds serply-api to the search services catalogue, next to serper-api. agentty has a matching PR that moves its submodule to this commit and adds the id to its registry list, so this one needs to be merged first.

Disclosure: I work with Serply.

What it does

Serply returns Google results as JSON (docs). The row is built the same way as Serper's:

  • Request: GET https://api.serply.io/v1/search/?q=...&num=... with the key in the x-api-key header, so the key never appears in the URL.
  • Country: defaults to United States. Without gl the request is served from whichever proxy region is free and the results can change country between calls, so gl=us is sent when the dial is empty. The dial is the shared list with "United States (default)" as its first row and no second US row; any other choice is sent as gl (lower case).
  • Freshness: Past hour to Past year, sent as tbs=qdr:h|d|w|m|y. These are the same values Serper offers.
  • Excluded sites: not in has_native_exclude, so -site: stays in the query text, as it does for Serper. Google honours it.
  • Reply: read from results[], using link, title and description. A 2xx reply without results is reported as unreadable.
  • Out of credits: Serply's gateway answers a zero balance (expired free credits included) with 402 and {"detail":"Insufficient prepaid credits"}, which classify_http already reports as quota exhausted.
  • Token links: now and then a reply row carries an opaque token in link instead of a URL. Rows whose link is not http(s) are dropped before counting.
  • Empty results on a 200: Serply's Pagination guide says this also happens during transient upstream failures. No header or field tells it apart from a genuine "no results"; the documented advice is to retry. mcp-cpp reports it as no results and moves to the next service.

Things that differ from Serper:

  • max_count is 10. num above 10 returns the same page as num=10.
  • No language. hl did not change the results, so the row leaves language off and does not claim it.
  • No spell-correction dial. Serply has no autocorrect parameter.
  • A user-agent: mcp-cpp header is sent. Cloudflare in front of the API refuses some default client user-agents, so the request names itself.

The builder comment marks this [L]: the exact URL the test pins, ?q=rust%20async&num=5&gl=nz&tbs=qdr%3Ad, returns 200 from the live API, and tbs=qdr:h narrowed the results.

Tests

tests/web_search_services_test.cpp:

  • the catalogue count goes from 10 to 11;
  • Serply's Freshness values are checked against the same hourly tbs list Serper uses;
  • a new case covers the request (URL, key header, user-agent, no hl, cap of 10, gl=us with no dials, no second US row) and the reply parser (a recorded result, and a reply without results);
  • the reply parser skips a row whose link is a token and does not count it;
  • "failures are told apart" pins Serply's 402 body as quota exhausted.

The full mcp_tests run passes (96 cases, 2269 assertions) with GCC 13, and the build has no warnings.

Google results over GET /v1/search with the X-Api-Key header. Country
goes out as gl and Freshness as tbs=qdr:, the same values Serper offers.
Serply stops at 10 results and its hl does not change them, so the row
caps at 10 and does not take the language.
Without gl, Serply serves each request from whichever proxy region is
free, so results can change country between calls. req_serply now sends
gl=us when the Country dial is empty, and the dial's default row reads
United States (default) in place of a second US row.

Also pins the zero-balance reply, a 402 with
{"detail":"Insufficient prepaid credits"}, as QuotaExhausted, and
skips reply rows whose link is an opaque token rather than a URL.
@googio
googio force-pushed the feat/serply-search branch from 5296871 to 8663d3c Compare October 17, 2026 22:17
@1ay1
1ay1 merged commit f133e69 into agentty-org:master Oct 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants