Skip to content

feat(parallel): add free Parallel Search MCP as the zero-config default web_search provider#90849

Merged
davemorin merged 6 commits into
openclaw:mainfrom
NormallyGaussian:feat/parallel-free-search-mcp-v2
Jun 7, 2026
Merged

feat(parallel): add free Parallel Search MCP as the zero-config default web_search provider#90849
davemorin merged 6 commits into
openclaw:mainfrom
NormallyGaussian:feat/parallel-free-search-mcp-v2

Conversation

@NormallyGaussian
Copy link
Copy Markdown
Contributor

@NormallyGaussian NormallyGaussian commented Jun 6, 2026

Note

AI-assisted PR. Implementation and iterative review were AI-driven (Claude), with codex review --base origin/main run repeatedly until it returned no actionable findings. The author reviewed every change, ran the live integration, and understands the code being merged.

Summary

What problem does this PR solve?

OpenClaw had no high-quality, zero-setup, free web search by default. With no API key and no provider configured, web_search fell back to DuckDuckGo (labeled "experimental", an unofficial HTML-based integration); high-quality Parallel search required a paid PARALLEL_API_KEY.

Why does this matter now?

We want every OpenClaw install to get a high-quality web search experience for free, with no account, key, or setup.

What is the intended outcome?

A new bundled provider, Parallel Search (Free) (parallel-free), backed by Parallel's free hosted Search MCP, becomes the zero-config web_search default (auto-detect order 76, ahead of the other key-free fallbacks). A fresh install returns LLM-optimized, ranked dense excerpts with no key. The existing paid Parallel Search (parallel) is used when PARALLEL_API_KEY is set.

What is intentionally out of scope?

No core architectural change and no new SDK surface. The generic web_search tool stays provider-agnostic (no provider name in its description, no tool-call relabeling). Other providers untouched. Auto-detect still prefers a configured keyed provider over the keyless default. CHANGELOG.md is left to release tooling.

What does success look like?

Fresh install (no key) selects parallel-free; PARALLEL_API_KEY selects parallel; any other configured provider/key still wins; the paid REST path is unchanged.

What should reviewers focus on?

Provider selection and default ordering (src/web-search/runtime.ts, src/secrets/runtime-web-tools.shared.ts); the hand-rolled Streamable-HTTP MCP client; the shared parallel-search-normalize.ts used by both runtimes; the doctor legacy-owner registry update; and that nothing provider-specific leaked into core.

Linked context

Which issue does this close?

Closes #

Which issues, PRs, or discussions are related?

Related #85158 (added the paid Parallel web_search provider that this builds on)

Was this requested by a maintainer or owner?

Authored by an OpenClaw maintainer as intended work, not drive-by churn.

Real behavior proof (required for external PRs)

  • Behavior or issue addressed: zero-config web_search resolves to parallel-free and returns live results from the free Search MCP; configured keys still win.
  • Real environment tested: macOS; fresh ~/.openclaw/openclaw.json; live calls to https://search.parallel.ai/mcp.
  • Exact steps or command run after this patch: from the repo root, wipe config, onboard with no auth, run the gateway, then search from the TUI in another window:
rm ~/.openclaw/openclaw.json
pnpm build && pnpm openclaw onboard --flow quickstart --accept-risk --auth-choice skip --skip-channels --skip-skills --skip-daemon --skip-ui --skip-health
pnpm openclaw gateway run --port 18789 --bind loopback --force
# in another window
pnpm openclaw tui
  • Evidence after fix: live screenshots from the run above. Search returns results with no key and no setup, and onboarding shows Parallel Search (Free) selected by default when no other API keys are present.

    Search is working (no keys, no setup):

    image

    Onboarding shows Parallel Search (Free) — selected by default if no other API keys are present:

    image
  • Observed result after fix: matches expected across all selection cases (no-key → parallel-free; PARALLEL_API_KEYparallel; BRAVE_API_KEYbrave; explicit provider → that provider).

  • What was not tested: cross-OS beyond macOS; sustained-load quota behavior on the free MCP.

  • Proof limitations or environment constraints: free MCP results vary over time.

Tests and validation

Which commands did you run?

pnpm build (no [INEFFECTIVE_DYNAMIC_IMPORT]); pnpm tsgo:core + tsgo:extensions; oxfmt/oxlint; pnpm test on extensions/parallel, src/web-search, src/secrets/runtime-web-tools, src/config/config.web-search-provider, src/flows/search-setup, src/plugins/contracts/providers.contract, and the doctor legacy-web-search-migrate suite. codex review --base origin/main: no actionable findings.

What regression coverage was added or updated?

New parallel-free provider tests + a dedicated MCP-client test (handshake, SSE/JSON parsing, envelope selection, model_name/session_id forwarding); contract/registration cases updated for the new provider id.

What failed before this fix, if known?

N/A — additive feature.

If no test was added, why not?

Tests were added.

Risk checklist

Did user-visible behavior change? Yes — the no-credential web_search default changes from DuckDuckGo to parallel-free.

Did config, environment, or migration behavior change? No new config/env; parallel-free has no legacy shape and is registered as non-migrated in the doctor owner map.

Did security, auth, secrets, network, or tool execution behavior change? New outbound host search.parallel.ai, routed through the existing withTrustedWebSearchEndpoint SSRF guard (same policy as the REST path); anonymous, no credentials sent.

What is the highest-risk area?

Provider auto-detect selection — ensuring the keyless default never overrides a configured keyed provider.

How is that risk mitigated?

Selection is covered by unit tests across the no-key, key-present, and explicit-provider cases; the keyless default only applies when no credential is configured.

Current review state

What is the next action?

Mark ready for review.

What is still waiting on author, maintainer, CI, or external proof?

Nothing outstanding — local checks + codex clean; repro and screenshots included above.

Which bot or reviewer comments were addressed?

Pre-submission codex review findings were all resolved before opening (final pass: no actionable findings).

…lt web_search provider

Registers two Parallel web_search providers in the parallel plugin:
- parallel-free: keyless, always the free hosted Search MCP (search.parallel.ai/mcp);
  the zero-config default (autoDetectOrder 76) so web_search works with no key.
- parallel: the existing paid v1 REST API (requires PARALLEL_API_KEY).

Shared query/result normalization lives in parallel-search-normalize.ts (used by both
transports); a minimal Streamable-HTTP JSON-RPC client (parallel-mcp-search.runtime.ts)
backs the free path. UI brands the tool-call chip 'Parallel Web Search' on the free path
via a searchTransport marker; setup default mirrors runtime auto-detect.
…wners

parallel-free is a bundled web_search provider, so add it to the doctor's
exhaustive BUNDLED_LEGACY_WEB_SEARCH_OWNERS map (owned by the parallel plugin)
and the NON_MIGRATED set — it has no legacy tools.web.search.* shape, so this is
a no-op for migration, matching paid parallel/tavily. Keeps the registry
complete. (Spotted by diffing the earlier local WIP branch.)
…I-label claim

- Frame the two providers as Parallel Search (Free) vs paid Parallel Search;
  remove internal 'v1 REST API' wording.
- Remove conversational/overstated phrasing ('out of the box for everyone').
- Remove the 'labeled Parallel Web Search in the UI' claim (only renders in the
  Control UI, not the TUI). Scope the searchTransport code comment accordingly.
The label only rendered in the Control UI, never the TUI (a separate renderer
via src/agents/tool-display.ts). Extending it would put provider-specific
labeling into a shared/core display path, against the plugin-agnostic-core rule.

Reverts the Control-UI labelOverride wiring and removes the now-orphaned
searchTransport marker from the free provider's result. The result still carries
provider: "parallel-free".
@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation commands Command implementations extensions: parallel size: XL triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. labels Jun 6, 2026
@clawsweeper
Copy link
Copy Markdown
Contributor

clawsweeper Bot commented Jun 6, 2026

Codex review: found issues before merge. Reviewed June 6, 2026, 1:49 AM ET / 05:49 UTC.

Summary
The PR adds a bundled keyless parallel-free Parallel Search MCP provider, registers it in the Parallel plugin/contracts/docs/setup flow, and places it ahead of existing keyless web_search fallbacks.

PR surface: Source +614, Tests +428, Docs +37. Total +1079 across 19 files.

Reproducibility: yes. for the review blocker: current main returns the first keyless fallback after credentialed providers fail, and this PR puts parallel-free at order 76 ahead of DuckDuckGo's order 100. I also inspected the supplied screenshots and ran a live anonymous Search MCP probe for the external tool contract.

Review metrics: 1 noteworthy metric.

  • Web search default: 1 changed. The PR changes the implicit no-credential managed web_search provider from DuckDuckGo to Parallel Search (Free), which maintainers should notice before merge.

Merge readiness
Overall: 🦐 gold shrimp
Proof: 🦞 diamond lobster ✨ media proof bonus
Patch quality: 🦐 gold shrimp
Result: needs maintainer review before merge.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • Resolve whether parallel-free should be opt-in first or the accepted zero-config default.
  • [P2] If keeping it as default, record the hosted endpoint, privacy, quota, and upgrade expectations in the PR before merge.

Risk before merge

  • [P1] Existing no-provider/keyless web_search users would silently move from DuckDuckGo to Parallel's hosted Search MCP and a new outbound host unless maintainers explicitly accept that default change.
  • [P1] The supplied proof covers a fresh macOS flow and a single live Search MCP path, but sustained free-tier quota, terms, and privacy expectations are still product/upgrade questions for a default provider.

Maintainer options:

  1. Keep Parallel Free Explicit First (recommended)
    Remove the default auto-detect ordering and default-language docs so the provider can land without changing existing keyless setups while maintainers decide default policy.
  2. Accept The New Default Deliberately
    Maintainers can choose to keep parallel-free as the zero-config default after recording the privacy, quota, outbound-host, and upgrade expectations.
  3. Pause If Default Ownership Is Unclear
    If OpenClaw core should not own this hosted-provider default, pause or close this branch and keep Parallel Free as plugin/ClawHub-oriented work instead.

Next step before merge

  • [P2] The remaining blocker is a maintainer/product acceptance decision for the default provider switch, not a narrow automated repair.

Security
Cleared: No concrete supply-chain or credential regression was found; the new anonymous outbound host uses the existing trusted endpoint helper, while the default-host switch remains a compatibility/privacy merge risk.

Review findings

  • [P1] Gate the keyless default switch — extensions/parallel/src/parallel-free-web-search-provider.shared.ts:20
Review details

Best possible solution:

Land parallel-free as an explicit selectable provider first, or merge the default switch only after maintainers explicitly accept the hosted-provider privacy, quota, and upgrade behavior while preserving keyed-provider precedence.

Do we have a high-confidence way to reproduce the issue?

Yes for the review blocker: current main returns the first keyless fallback after credentialed providers fail, and this PR puts parallel-free at order 76 ahead of DuckDuckGo's order 100. I also inspected the supplied screenshots and ran a live anonymous Search MCP probe for the external tool contract.

Is this the best way to solve the issue?

No, not as-is. The provider implementation and MCP session repair are plausible, but the best maintainable path is either opt-in first or an explicit maintainer decision accepting the zero-config hosted-provider default and its upgrade/privacy/quota implications.

Full review comments:

  • [P1] Gate the keyless default switch — extensions/parallel/src/parallel-free-web-search-provider.shared.ts:20
    With requiresCredential: false and autoDetectOrder: 76, this provider becomes the first keyless fallback because current main defers keyless providers until credentialed candidates fail and then returns the first one by auto-detect order. That silently moves existing no-provider installs from DuckDuckGo to search.parallel.ai; please either make parallel-free explicit/opt-in or include the maintainer-approved default and upgrade/privacy/quota decision before merge.
    Confidence: 0.91

Overall correctness: patch is incorrect
Overall confidence: 0.9

AGENTS.md: found and applied where relevant.

Codex review notes: model gpt-5.5, reasoning high; reviewed against 153a2badb056.

Label changes

Label changes:

  • add proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes after-fix macOS steps and screenshots that I inspected, showing TUI search output and onboarding selecting Parallel Search (Free) by default.

Label justifications:

  • P2: This is a normal-priority feature/default change with compatibility impact but no evidence of a release-blocking outage.
  • merge-risk: 🚨 compatibility: Merging would change existing keyless users' implicit web_search provider and outbound host from DuckDuckGo to Parallel's hosted Search MCP.
  • rating: 🦐 gold shrimp: Overall readiness is 🦐 gold shrimp; proof is 🦞 diamond lobster and patch quality is 🦐 gold shrimp.
  • status: ⏳ waiting on author: ClawSweeper has contributor-facing work open and is waiting for author action. Sufficient (screenshot): The PR body includes after-fix macOS steps and screenshots that I inspected, showing TUI search output and onboarding selecting Parallel Search (Free) by default.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes after-fix macOS steps and screenshots that I inspected, showing TUI search output and onboarding selecting Parallel Search (Free) by default.
  • proof: 📸 screenshot: Contributor real behavior proof includes screenshot evidence. The PR body includes after-fix macOS steps and screenshots that I inspected, showing TUI search output and onboarding selecting Parallel Search (Free) by default.
Evidence reviewed

PR surface:

Source +614, Tests +428, Docs +37. Total +1079 across 19 files.

View PR surface stats
Area Files Added Removed Net
Source 14 814 200 +614
Tests 3 433 5 +428
Docs 2 68 31 +37
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 19 1315 236 +1079

What I checked:

Likely related people:

  • NormallyGaussian: The merged Parallel provider PR introduced the bundled Parallel web_search runtime, docs, contracts, and tests that this PR extends. (role: feature owner / recent area contributor; confidence: high; commits: db7d70ae4d9f; files: extensions/parallel/src/parallel-web-search-provider.runtime.ts, extensions/parallel/src/parallel-web-search-provider.shared.ts, docs/tools/parallel-search.md)
  • Shakker: Current-main blame for resolveWebSearchProviderId and the search setup default path points to this author; the PR changes the behavior those paths select by adding a new earlier keyless provider. (role: adjacent owner; confidence: medium; commits: 03b35b53e36e; files: src/web-search/runtime.ts, src/flows/search-setup.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@clawsweeper clawsweeper Bot added rating: 🌊 off-meta tidepool PR readiness rating does not apply to this item. proof: sufficient ClawSweeper judged the real behavior proof convincing. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. and removed rating: 🌊 off-meta tidepool PR readiness rating does not apply to this item. labels Jun 6, 2026
@openclaw-barnacle openclaw-barnacle Bot added proof: supplied External PR includes structured after-fix real behavior proof. and removed triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. proof: sufficient ClawSweeper judged the real behavior proof convincing. labels Jun 6, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label Jun 6, 2026
…ist contract

The free parallel-free provider reused the paid ParallelSearchSchema, whose
session_id allows 1000 chars, but the live Search MCP tools/list schema caps
session_id at 100. Parameterize normalizeParallelSessionId(value, maxLength);
the free path passes 100 (paid keeps 1000) and advertises the tighter bound in
its own ParallelFreeSearchSchema. An over-limit caller id is dropped and a
fresh in-contract id is minted. Updates tests and docs accordingly.
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label Jun 6, 2026
@NormallyGaussian NormallyGaussian marked this pull request as ready for review June 6, 2026 05:41
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label Jun 6, 2026
@davemorin
Copy link
Copy Markdown
Member

Thank you for the update to open, free, keyless search.

@davemorin davemorin merged commit 983b65b into openclaw:main Jun 7, 2026
211 of 213 checks passed
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jun 7, 2026
…lt web_search provider (openclaw#90849)

* feat(parallel): add free Parallel Search MCP as the zero-config default web_search provider

Registers two Parallel web_search providers in the parallel plugin:
- parallel-free: keyless, always the free hosted Search MCP (search.parallel.ai/mcp);
  the zero-config default (autoDetectOrder 76) so web_search works with no key.
- parallel: the existing paid v1 REST API (requires PARALLEL_API_KEY).

Shared query/result normalization lives in parallel-search-normalize.ts (used by both
transports); a minimal Streamable-HTTP JSON-RPC client (parallel-mcp-search.runtime.ts)
backs the free path. UI brands the tool-call chip 'Parallel Web Search' on the free path
via a searchTransport marker; setup default mirrors runtime auto-detect.

* chore(parallel): register parallel-free in doctor legacy-web-search owners

parallel-free is a bundled web_search provider, so add it to the doctor's
exhaustive BUNDLED_LEGACY_WEB_SEARCH_OWNERS map (owned by the parallel plugin)
and the NON_MIGRATED set — it has no legacy tools.web.search.* shape, so this is
a no-op for migration, matching paid parallel/tavily. Keeps the registry
complete. (Spotted by diffing the earlier local WIP branch.)

* docs(parallel): restore concise frontmatter summary

* docs(parallel): clearer, professional copy; drop v1 REST jargon and UI-label claim

- Frame the two providers as Parallel Search (Free) vs paid Parallel Search;
  remove internal 'v1 REST API' wording.
- Remove conversational/overstated phrasing ('out of the box for everyone').
- Remove the 'labeled Parallel Web Search in the UI' claim (only renders in the
  Control UI, not the TUI). Scope the searchTransport code comment accordingly.

* revert(parallel): drop the "Parallel Web Search" tool-call branding

The label only rendered in the Control UI, never the TUI (a separate renderer
via src/agents/tool-display.ts). Extending it would put provider-specific
labeling into a shared/core display path, against the plugin-agnostic-core rule.

Reverts the Control-UI labelOverride wiring and removes the now-orphaned
searchTransport marker from the free provider's result. The result still carries
provider: "parallel-free".

* fix(parallel): cap free Search MCP session_id at its 100-char tools/list contract

The free parallel-free provider reused the paid ParallelSearchSchema, whose
session_id allows 1000 chars, but the live Search MCP tools/list schema caps
session_id at 100. Parameterize normalizeParallelSessionId(value, maxLength);
the free path passes 100 (paid keeps 1000) and advertises the tighter bound in
its own ParallelFreeSearchSchema. An over-limit caller id is dropped and a
fresh in-contract id is minted. Updates tests and docs accordingly.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

commands Command implementations docs Improvements or additions to documentation extensions: parallel merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. P2 Normal backlog priority with limited blast radius. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. proof: sufficient ClawSweeper judged the real behavior proof convincing. proof: supplied External PR includes structured after-fix real behavior proof. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. size: XL status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants