Skip to content

feat(toolset): add Serply search toolset - #1088

Open
googio wants to merge 1 commit into
xpert-ai:mainfrom
googio:feat/serply-search
Open

googio wants to merge 1 commit into
xpert-ai:mainfrom
googio:feat/serply-search

Conversation

@googio

@googio googio commented Sep 25, 2026 •

Copy link
Copy Markdown

PR

Adds a serply builtin toolset next to tavily, searchapi and serper, 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, one serply_search tool that calls GET https://api.serply.io/v1/search and 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_key is required; num (1 to 10), gl (country) and hl (language) are optional and passed through as query parameters.
  • provider/builtin/serply/serply.ts: SerplyToolset, using initTools() and isToolEnabled like TavilyToolset. _validateCredentials runs a one-result search.
  • provider/builtin/serply/tools/serply-search.ts: the StructuredTool. The response is read at the trust boundary with a type guard (title and link must 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.yaml and _assets/icon.svg.
  • provider/builtin/index.ts: registers the toolset.
  • i18n/{en,en-US,zh-Hans}.json: Tools.SerplySearch.WebSearch for 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: xpert so 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.ts mocks fetch and 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.

corepack pnpm exec jest -c packages/server-ai/jest.config.ts packages/server-ai/src/xpert-toolset/provider/builtin/serply
Tests:       4 passed, 4 total

corepack pnpm exec tsc -p packages/server-ai/tsconfig.lib.json --noEmit
(no errors)

corepack pnpm exec eslint <changed .ts files>
0 errors (one pre-existing no-explicit-any warning in index.ts, not from this change)

The xpert-toolset/queries, dto and provider/builtin specs pass. Two suites under xpert-toolset fail for me before and after this change and do not touch these files: utils/parser.spec.ts (an OpenAPI fixture) and get-odata-remote-metadata.handler.test.ts (needs dist/packages/server).

Manual: a live search with a real key through SerplySearch.invoke returns the mapped results, and a wrong key surfaces as HTTP 401.

Checklist

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.

yurongk commented Sep 28, 2026

Copy link
Copy Markdown
Contributor

Thanks a lot for the contribution, and for the clean implementation!

One thought on direction: Xpert's MCP consumer already supports Streamable HTTP, api_key/header auth, tool discovery with per-tool enable/disable, and plugin-managed MCP servers. Serply's hosted MCP endpoint (https://api.serply.io/mcp, X-Api-Key) fits that path directly and exposes all 14 Serply tools, while this PR adds one REST-based tool as a new builtin provider.

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 WebSearch timeline mapping and the normalized { title, url, content } shape are valuable, and we'd prefer to solve those generically for search-type MCP tools so every provider benefits.

Happy to help with the plugin side. Thanks again!

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

2 participants