Conversation
Adds a serply builtin toolset with one serply_search tool that calls the Serply search API and reports results as a web-search step, following the Tavily toolset shape.
|
Thanks a lot for the contribution, and for the clean implementation! One thought on direction: Xpert's MCP consumer already supports Streamable HTTP, Would you be open to shipping this as a plugin-managed MCP integration instead (a thin plugin declaring the Serply MCP server, icon, default tools and policy)? The Happy to help with the plugin side. Thanks again! |
PR
Adds a
serplybuiltin toolset next totavily,searchapiandserper, so an expert can search Google through Serply with a Serply API key. It follows the shape of the Tavily toolset: a provider manifest with the credential form, oneserply_searchtool that callsGET https://api.serply.io/v1/searchand returns each result as{ title, url, content }, and a web-search step event so the computer timeline renders the results the same way it does for Tavily.What is in the change:
provider/builtin/serply/serply.yaml: provider identity and credentials.serply_api_keyis required;num(1 to 10),gl(country) andhl(language) are optional and passed through as query parameters.provider/builtin/serply/serply.ts:SerplyToolset, usinginitTools()andisToolEnabledlikeTavilyToolset._validateCredentialsruns a one-result search.provider/builtin/serply/tools/serply-search.ts: theStructuredTool. The response is read at the trust boundary with a type guard (titleandlinkmust be strings), so a malformed item is dropped rather than cast. A non-2xx status throws with the HTTP status, which is what surfaces in the credential validation dialog on a wrong key.provider/builtin/serply/tools/serply_search.yamland_assets/icon.svg.provider/builtin/index.ts: registers the toolset.i18n/{en,en-US,zh-Hans}.json:Tools.SerplySearch.WebSearchfor the step title, per the backend i18n rule in AGENTS.md.Nothing changes for anyone who does not add the toolset: no new dependency, no new environment variable, and the other search toolsets are untouched. The request sends
User-Agent: xpertso the traffic is identifiable on the API side.Disclosure: I work on Serply. Happy to adjust scope, naming, or drop this entirely if it isn't a direction you want for the project. I am ready to sign the individual Contributor Assignment Agreement: if the CLA assistant check does not appear on this PR, send me the signing link and I will complete it.
Testing
packages/server-ai/src/xpert-toolset/provider/builtin/serply/tools/serply-search.spec.tsmocksfetchand covers the request (URL,X-Api-Key,User-Agent,num,gl), the result mapping and the dropped malformed item, an empty body, a 401, and the missing-key constructor error.The
xpert-toolset/queries,dtoandprovider/builtinspecs pass. Two suites underxpert-toolsetfail for me before and after this change and do not touch these files:utils/parser.spec.ts(an OpenAPI fixture) andget-odata-remote-metadata.handler.test.ts(needsdist/packages/server).Manual: a live search with a real key through
SerplySearch.invokereturns the mapped results, and a wrong key surfaces asHTTP 401.Checklist