From 7f882415c015ffb75d2e97dc418ec2b4cdd7f780 Mon Sep 17 00:00:00 2001 From: georgeatparallel Date: Fri, 9 Oct 2026 03:38:04 +0000 Subject: [PATCH] feat: add Parallel search example --- docs/client/examples.md | 13 +++++ .../client/parallelSearchClient.scala | 49 +++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 examples/src/main/scala/examples/client/parallelSearchClient.scala diff --git a/docs/client/examples.md b/docs/client/examples.md index c253e1a6..ee3a9be9 100644 --- a/docs/client/examples.md +++ b/docs/client/examples.md @@ -153,3 +153,16 @@ object BidirectionalPekkoClient: ``` More runnable examples live in [`examples/`](https://github.com/softwaremill/chimp/tree/master/examples/src/main/scala/examples). + +## Parallel web search and fetch + +The [Parallel Search MCP](https://docs.parallel.ai/integrations/mcp/search-mcp) example connects to a public server with `ClientHttpTransport`. It lists the tools, calls `web_search` with your query, and calls `web_fetch` with your URL. It prints the returned text and closes the client and HTTP backend. + +From the repository root, use [Scala CLI](https://scala-cli.virtuslab.org/) to run the example: + +```bash +scala-cli run examples/src/main/scala/examples/client/parallelSearchClient.scala --jvm 21 -- \ + "Scala MCP client HTTP transport" "https://chimp.softwaremill.com/client/transport.html" +``` + +The file declares its dependencies. No API key or local server is required. The anonymous endpoint is free for light use and has rate limits. This example calls the tools directly. diff --git a/examples/src/main/scala/examples/client/parallelSearchClient.scala b/examples/src/main/scala/examples/client/parallelSearchClient.scala new file mode 100644 index 00000000..d38b96b9 --- /dev/null +++ b/examples/src/main/scala/examples/client/parallelSearchClient.scala @@ -0,0 +1,49 @@ +//> using dep com.softwaremill.chimp::chimp-client:0.6.0 +//> using dep com.softwaremill.sttp.client4::core:4.0.27 + +package examples.client + +import chimp.client.* +import chimp.client.transport.ClientHttpTransport +import chimp.protocol.* +import io.circe.Json +import sttp.client4.DefaultSyncBackend +import sttp.model.Header +import sttp.model.Uri.UriContext +import sttp.shared.Identity + +import java.util.UUID + +@main def parallelSearchClient(query: String, url: String): Unit = + val backend = DefaultSyncBackend() + try + val transport = ClientHttpTransport[Identity]( + backend, + uri"https://search.parallel.ai/mcp", + headers = Seq(Header("User-Agent", "chimp-parallel-search-example/0.1.0")) + ) + val client = McpClient[Identity](transport, Implementation("chimp-parallel-search-example", "0.1.0")) + try + val tools = client.listTools().tools.map(_.name) + require(tools.contains("web_search") && tools.contains("web_fetch"), "Search and fetch tools are required") + val sessionId = UUID.randomUUID().toString + + val search = client.callTool( + "web_search", + Json.obj( + "objective" -> Json.fromString(query), + "search_queries" -> Json.arr(Json.fromString(query)), + "session_id" -> Json.fromString(sessionId) + ) + ) + search.content.collect { case ToolContent.Text(_, text) => text }.foreach(println) + require(!search.isError, "Web search failed") + + val fetch = client.callTool( + "web_fetch", + Json.obj("urls" -> Json.arr(Json.fromString(url)), "session_id" -> Json.fromString(sessionId)) + ) + fetch.content.collect { case ToolContent.Text(_, text) => text }.foreach(println) + require(!fetch.isError, "Web fetch failed") + finally client.close() + finally backend.close()