
migrate-to-parallel
Migrate Exa, Tavily, Perplexity, or Firecrawl web-data integrations completely to the appropriate Parallel products while preserving application behavior. Use when replacing these providers' SDKs or REST calls, dependencies, environment variables, request parameters, response parsing, model tools, search-plus-scrape paths, full-content or answer-synthesis paths, tests, and documentation; separating unsupported research-index, crawl, browser, file-parse, monitor, or other non-search capabilities; auditing for leftover provider usage; or finishing and verifying an in-progress provider migration.
- Installs
- 3.2K
- Last 24h
- +26
- Trending rank
- #4815
- Security
- Not audited
Install
Works with every agent the skills CLI supports.
npx skills add https://github.com/parallel-web/parallel-agent-skills --skill migrate-to-parallel- 01
Install
Run the command in your project. The CLI asks which agents to install for.
- 02
Describe the task
Ask your agent for something this skill covers. It loads migrate-to-parallel automatically when relevant.
- 03
Review the result
The agent follows the SKILL.md steps, scripts and references bundled with the skill.
SKILL.md
The instructions your agent reads when the skill is triggered.
Migrate to Parallel
Replace the provider boundary end to end. Treat a successful HTTP response as the midpoint, not completion: migrate request construction, response consumers, dependencies, configuration, tests, and operational behavior.
Resolve <skill-root> to the directory containing this SKILL.md. Resolve every bundled reference and script from that directory, regardless of the current working directory. The scanner uses only the Python standard library. If Python 3.9 or newer is unavailable, perform equivalent repository searches with the harness's file-search tools and state that the bundled scan was not run.
Load the right references
- Read references/exa.md when the repository contains Exa.
- Read references/tavily.md when the repository contains Tavily.
- Read references/perplexity.md when the repository contains Perplexity Search, Sonar, Agent API web tools, or a Perplexity search wrapper.
- Read references/firecrawl.md when the repository contains Firecrawl Search, Scrape, Batch Scrape, Extract, Agent, Research Index, Crawl, Map, Parse, Browser, Interact, Monitor, or MCP usage.
- Read references/parallel-search.md when any call may route to Search or needs query, filter, freshness, mode, or result-list migration.
- Read references/parallel-products.md when any call may route to Extract, Chat, Task, or entity discovery, or needs streaming, structured output, or citations.
- Read references/integration-patterns.md when queries are generated dynamically, the provider is exposed as a model tool, provider response types escape into multiple modules, or the application needs full content or synthesized answers.
- Open current official documentation for any detected SDK, wrapper, parameter, or response field not covered by those references. Do not guess at provider behavior.
Preserve these invariants
- Preserve caller-visible behavior unless the user explicitly authorizes a change.
- Never silently drop a filter, content field, synthesized answer, image, safety control, or score-based decision.
- Never print API keys or secret values. Check only whether a key is present.
- Do not add a hidden LLM call merely to manufacture
search_queries. - Do not treat an arbitrary user prompt as a keyword query merely because it fits an API length limit.
- Keep web-research intent, hard filters, handler policy, and answer-synthesis instructions in their separate contracts.
- Treat omitted provider parameters as behavior too: inspect their defaults before omitting a Parallel setting.
- Do not recreate the entire legacy provider SDK behind a compatibility shim. Normalize only the contract the application actually uses.
- Do not remove credentials from external secret managers or provider dashboards unless the user explicitly asks. Remove obsolete code references and update checked-in templates.
- Treat mode mappings as starting points. Verify latency, quality, and output behavior with the application's real queries.
- Stop before destructive edits when a required behavior has no supported Parallel equivalent and no in-scope substitute. Report the exact gap and the smallest decision needed.
- Stop when the Perplexity boundary requires embeddings; they are not a Parallel Search replacement. Route
finance_searchthrough Parallel's general index using Search, Chat, or Task according to the consumed contract, and stop only when a hard market-data coverage, freshness, or raw-result requirement remains unpreserved. Keep Agent API model routing, sandbox, MCP, and existing custom-function capabilities separate unless the user explicitly expands the migration scope. - Stop when the Firecrawl boundary requires complete crawling or URL mapping, local/private file parsing, browser actions or sessions, screenshots or other rich scrape formats, change tracking, or Firecrawl-specific privacy/security controls without an approved replacement. Search and Extract do not reproduce those contracts.
- Follow repository-local instructions such as
AGENTS.md,CLAUDE.md, andCONTRIBUTING.md. Preserve unrelated work and never reset or discard user changes. - Complete safe repository-local migration work without stopping after an inventory or plan. Do not commit, push, change hosted secrets, or alter provider accounts unless the user asks.
1. Inventory the real migration surface
Record the current branch and working-tree state before editing. Run the bundled scanner from the target repository:
python3 <skill-root>/scripts/scan_provider_usage.py .
Use --format json for machine-readable output. The scanner intentionally skips dependency/generated directories, binaries, unreadable files, and oversized files; it cannot identify provider-neutral consumers from field names alone. Treat it as an inventory aid, not proof of completeness. Inspect the results and then trace each provider response to its consumers. Also inspect:
- package manifests and lockfiles;
- direct REST endpoints and auth headers;
- SDK clients, async clients, wrappers, and model-tool definitions;
- environment schemas, examples, deployment config, and docs;
- request builders, retries, timeouts, caches, observability, and error handling;
- response fields used for rendering, ranking, thresholds, citations, or model context;
- Firecrawl crawl, batch, extract, browser, interaction, webhook, and job-lifecycle consumers;
- tests, mocks, fixtures, and snapshots.
Run the existing focused tests before editing when feasible. Record which behavior is currently covered, which failures are pre-existing, and which behavior must be verified manually.
Before editing, write a decision row for every provider call site:
| Call site | Provider product | Consumed behavior | Parallel route | Semantic gap | Action |
|---|---|---|---|---|---|
path:line | Search, Scrape, Agent, etc. | Inputs, outputs, lifecycle, and policy the caller relies on | Exact product path, if any | Anything the route cannot preserve | migrate, retain, or block |
Choose exactly one action before changing the call:
migrateonly when the proposed route preserves the consumed contract or the user has already approved the named difference;retainwhen the call is outside the migration boundary or is the smallest safe way to preserve an unsupported capability;blockwhen the requested boundary cannot be completed without a user decision. Name the smallest decision, and continue any independentmigraterows.
Do not use a broader Parallel product merely to eliminate a provider import. A plausible result shape is not evidence that source scope, spend controls, model behavior, lifecycle, or privacy policy remains equivalent.
2. Choose the migration boundary
Consider both designs before editing:
- Direct replacement: Use when provider calls are few, nearby, and provider-specific response types do not escape. Replace each call and its consumers atomically.
- Application-owned web-data module: Use when calls are scattered, several Parallel products are needed, or provider fields escape into the application. Put request construction, response normalization, retries, and telemetry behind one small caller-facing interface. Make this a deep module that hides provider details; do not add a pass-through wrapper.
Prefer the design that localizes future search-provider changes and minimizes edits to unrelated callers. If the application publishes the old provider's raw response, either preserve only the documented application contract through a normalizer or update all consumers together.
3. Migrate requests intentionally
Build every Parallel Search API request around these facts:
search_queriesis required. Supply at least one non-empty keyword query; use two or three diverse keyword queries when the calling flow can provide them.objectiveis optional but recommended. Put the self-contained web-research goal there, not the whole user conversation or answer-format instructions.- Use
https://api.parallel.ai/v1/search,x-api-key, andPARALLEL_API_KEYfor direct REST calls. - Use the official
parallel-webpackage for both Python and TypeScript unless the detected framework has a current first-party Parallel integration that preserves the needed contract.
Classify every legacy input before translating it:
- full web-research goal, context, or soft source/freshness preference →
objective; - concise retrieval probes →
search_queries; - must-only or must-never source restrictions →
advanced_settings.source_policy; - answer format, synthesis instructions, structured output, or streaming → the existing synthesis layer, Chat API, or Task API;
- latency, result count, cache, and excerpt controls → application-owned policy chosen and tested explicitly.
For static calls, write an explicit objective and two or three keyword probes. For model tools, use the exact-three-query schema in references/integration-patterns.md. A one-query direct-call fallback is only for an already keyword-style legacy value and must be evaluated. Do not silently truncate intent, invent keyword variants, add a hidden planner, or move hard filters into prose.
Apply the provider mapping only after that classification. Preserve only settings that implement a real product requirement; unnecessary advanced_settings can reduce quality.
Validate runtime values against the Parallel V1 contract before sending them. Pay particular attention to query count/length, objective length, the combined 200-domain limit, date normalization, and supported location codes. Do not carry the old provider's numeric ranges forward implicitly.
4. Migrate response behavior
Update every consumer to the Parallel response shape. The Search API returns ranked results with url, optional title, optional publish_date, and an excerpts array. It does not return the old provider's relevance score, generated answer, image fields, response time, or full-page body.
Preserve field semantics, not just field names. A date-only publish_date does not restore an old timestamp's time-of-day precision, a search_id is not a session identifier, and SKU usage counts are not provider credits or dollar cost. Normalize only when the application contract defines the conversion; otherwise make the contract change explicit.
Route non-search behavior explicitly:
- Use Search API excerpts directly for LLM context or concise evidence.
- Use the Extract API for full content from known result URLs, reusing the Search API
session_id. - Use the Chat API or the application's existing model for a grounded answer.
- Use the Task API for asynchronous multi-step research or structured synthesis.
- Use Entity Search for synchronous people or company discovery.
For Firecrawl, classify the product before choosing a route. Search generally maps to Search; public-URL markdown or full content may map to Extract; structured multi-page research may map to Task only when Task preserves the required source scope, spend policy, quality choice, and lifecycle. Exact known-URL structured extraction instead favors Extract plus an application-owned model/parser. Research Index, Crawl, Map, Parse uploads, Browser, Interact, Monitor, screenshots, and other rich scrape behavior are not Search field mappings. Follow references/firecrawl.md and preserve separate capabilities until an explicit replacement is approved.
Do not fill missing fields with plausible-looking constants. Remove obsolete consumers, redesign the application contract, or use the appropriate Parallel API.
5. Replace dependencies and configuration
- Add only the SDKs required by the chosen routes:
parallel-webfor Search, Extract, or Task;openaifor Chat unless the application already has a compatible client; no SDK when direct REST is the simpler existing pattern. - Remove a legacy provider package only when no
retainrow still depends on it, then regenerate the lockfile with the repository's package manager. - Replace provider imports, client initialization, endpoints, and headers only inside
migraterows. Keep shared provider setup until retained calls have their own explicit boundary. - Add
PARALLEL_API_KEYto checked-in environment templates, validation schemas, setup scripts, deployment manifests, examples, and docs. Remove a legacy key from those surfaces only when no retained runtime capability still needs it. - Preserve existing timeout, retry, cancellation, and logging behavior where the Parallel SDK supports it; otherwise implement the behavior at the application boundary and test it.
- Keep error messages provider-neutral unless the provider name helps the operator act.
Never expose or rewrite real secret values in logs, reports, patches, or fixtures.
6. Verify behavior, not just syntax
Add or update tests for:
- request construction, including
search_queries, mode, filters, dates, and location; - source-policy normalization for apex domains, subdomains, schemes, paths, wildcards, conflicting lists, and provider-specific limits;
- query-design behavior: static requests, direct one-query compatibility paths, and model-tool schemas;
- omitted legacy defaults, dual domain lists, and any approved semantic change;
- target-limit validation for dynamic queries and domain lists;
- response parsing and excerpt joining;
- empty results, missing optional titles/dates, warnings, and errors;
- any normalizer that preserves an application-owned contract;
- full-content, synthesis, or entity routes when used;
- removal of score thresholds or provider-specific fields.
Preserve the repository's test execution contract. If its focused tests previously stubbed the provider package and ran without installing that SDK, stub the replacement SDK or keep imports behind the injected boundary too. Rerun the exact pre-migration test command in an equivalently clean environment; a pass that depends on an ambient package is not evidence that the repository remains self-contained.
Then run, in order:
- the narrow migration tests;
- the repository's formatter, type checker, lint, build, and broader tests as appropriate;
python3 <skill-root>/scripts/scan_provider_usage.py . --provider <legacy-provider> --fail-on-legacywhen that provider is being removed completely;- when approved non-search Perplexity or Firecrawl usage remains, run the provider scan without
--fail-on-legacy, classify every finding, and then scan only the migrated roots or use narrow--excludepaths for isolated retained modules; never exclude a mixed search/non-search boundary; - an independent case-insensitive search for
exa,tavily,perplexity,sonar-,firecrawl, exactmodelassignments tosonar, routedperplexity/sonarmodel IDs, package names, endpoints, and key names, excluding<skill-root>if the skill is installed inside the target repository; - a review of the final diff for unintended behavior changes, leaked values, unrelated edits, and stale lockfiles;
- a live smoke test only when provider calls are explicitly authorized for this task and
PARALLEL_API_KEYis already available, without printing it.
An ambient credential does not by itself authorize a paid network call. When authorized, use a small, non-sensitive synthetic query and inspect warnings, result ordering, excerpts, and error behavior. Compare representative production queries only when the user approves sending them to both providers or an existing repository test policy already permits that exact comparison. Do not require the user to paste secrets.
Completion gate
Finish only when all applicable statements are true:
- No legacy-provider runtime dependency, import, endpoint, auth header, key reference, tool definition, fixture, or stale setup instruction remains inside the migrated boundary.
- Any Perplexity model-routing, embeddings, sandbox, MCP, or custom-function capability outside that boundary remains intact or is called out as an explicit blocker.
- Any migrated
finance_searchpath preserves the consumed final-answer orfinance_resultscontract through an evaluated Parallel route and, when needed, an application-owned normalizer; unresolved hard coverage or freshness requirements are explicit blockers. - Any Firecrawl crawl, map, file-parse, browser, interaction, rich-format, change-tracking, security/privacy, MCP, or asynchronous-job capability outside that boundary remains intact or is called out as an explicit blocker.
- Every inventoried call has a recorded
migrate,retain, orblockdecision, and noblockrow was edited as though the gap were resolved. - Firecrawl exact-URL constraints, per-run credit ceilings,
spark-1-*model choices, and synchronous/asynchronous behavior are preserved or changed only with explicit approval; a domain allow-list, omitted budget, or guessed Task processor does not satisfy this gate. - Every used request feature and response field has an implemented Parallel path or an explicitly approved behavior change.
- Query construction preserves the research goal, uses keyword-shaped retrieval probes, and follows the applicable direct-call or model-tool contract.
- Source-policy migration preserves the intended URL scope; unsupported path or wildcard behavior is implemented explicitly or recorded as an approved gap.
- Tests and static checks pass, or unrelated pre-existing failures are identified with evidence.
- The provider-specific legacy scan passes when the provider was removed completely. Otherwise, every remaining finding belongs to an approved, isolated non-search boundary and every identified response has been traced through its downstream consumers.
- A live call passes when it was explicitly authorized and credentials are available; otherwise the missing live verification is stated clearly.
- The final report names the migrated boundary, important semantic choices, verification commands, and any external secret cleanup still left to the operator.
FAQ
What does the migrate-to-parallel skill do?
Migrate Exa, Tavily, Perplexity, or Firecrawl web-data integrations completely to the appropriate Parallel products while preserving application behavior. Use when replacing these providers' SDKs or REST calls, dependencies, environment variables, request parameters, response parsing, model tools, search-plus-scrape paths, full-content or answer-synthesis paths, tests, and documentation; separating unsupported research-index, crawl, browser, file-parse, monitor, or other non-search capabilities; auditing for leftover provider usage; or finishing and verifying an in-progress provider migration.
How do I install migrate-to-parallel?
Run npx skills add https://github.com/parallel-web/parallel-agent-skills --skill migrate-to-parallel in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/migrate-to-parallel/ (personal) or .claude/skills/migrate-to-parallel/ (project).
Which AI agents can use migrate-to-parallel?
Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.
Is migrate-to-parallel safe to install?
No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.
Who maintains migrate-to-parallel?
It is published by parallel-web in parallel-web/parallel-agent-skills. It has 3,242 recorded installs.
More from parallel-web/parallel-agent-skills
parallel-deep-research
parallel-web/parallel-agent-skills
ONLY use when user explicitly says 'deep research', 'exhaustive', 'comprehensive report', or 'thorough investigation'. Slower and more expensive than parallel-web-search. For normal research/lookup requests, use parallel-web-search instead. Supports follow-ups with a known prior Task interaction ID.
parallel-web-search
parallel-web/parallel-agent-skills
CLI-backed web search. Use when the user explicitly invokes this skill, needs CLI-only controls or saved JSON output, or no Parallel websearch MCP tool is available. When the bundled Parallel Search MCP is available, prefer its websearch tool for ordinary lookups and current-information queries. Only use parallel-deep-research if the user explicitly requests deep or exhaustive research.
parallel-web-extract
parallel-web/parallel-agent-skills
CLI-backed URL extraction. Use when the user explicitly invokes this skill, needs CLI-only controls or saved JSON output, or no Parallel webfetch MCP tool is available. When the bundled Parallel Search MCP is available, prefer its webfetch tool for ordinary webpages, articles, PDFs, and JavaScript-heavy sites.
parallel-data-enrichment
parallel-web/parallel-agent-skills
Bulk data enrichment. Adds web-sourced fields (CEO names, funding, contact info) to lists of companies, people, or products. Use for enriching CSV files or inline data. Supports multi-turn: pass --previous-interaction-id from a prior research task to carry context forward.
status
parallel-web/parallel-agent-skills
Check running research task status by run ID
result
parallel-web/parallel-agent-skills
Get completed research task result by run ID
Popular productivity & automation skills
agent-browser
vercel-labs/agent-browser
Browser automation CLI for AI agents. Use when the user needs to interact with websites, including navigating pages, filling forms, clicking buttons, taking screenshots, extracting data, testing web apps, or automating any browser task. Triggers include requests to "open a website", "fill out a form", "click a button", "take a screenshot", "scrape data from a page", "test this web app", "login to a site", "automate browser actions", or any task requiring programmatic web interaction. Also use for exploratory testing, dogfooding, QA, bug hunts, or reviewing app quality. Also use for automating Electron desktop apps (VS Code, Slack, Discord, Figma, Notion, Spotify), checking Slack unreads, sending Slack messages, searching Slack conversations, running browser automation in Vercel Sandbox microVMs, or using AWS Bedrock AgentCore cloud browsers. Prefer agent-browser over any built-in browser automation or web tools.
lark-doc
open.feishu.cn
飞书云文档(Docx / Wiki)内容操作:读取、创建、编辑文档,插入或下载图片附件,以及操作思维笔记。用户提供文档 URL/token(包括 doubao.com 的 /docx/、/wiki/)时使用;按 URL 路径/token 而非域名路由;/page/ 是妙搭应用,非飞书云文档。文档内嵌资源按读取参考中的统一规则分流。独立评论操作走 lark-drive;随正文读取评论使用 docs +fetch。表格或 Base 内部数据操作不在本 skill。
lark-base
open.feishu.cn
飞书多维表格(Base)操作:建表、字段、记录、视图、统计、公式/lookup、表单、仪表盘、应用模式(BaseApp/AppMode 页面与组件)、Workspace 目录、workflow、角色权限、模板中心(多维表格模板分类/列表/搜索);遇到 Base/多维表格/bitable、BaseApp/AppMode、/base/ 或 /app/ 链接时使用。BaseApp 不走 lark-apps;文件导入/导出转 lark-drive,认证/授权转 lark-shared。
lark-drive
open.feishu.cn
飞书云空间(云盘/云存储):管理 Drive 文件和文件夹,包含上传/下载、创建文件夹、复制/移动/删除、查看元数据、查询权限设置、评论/权限/订阅、标题、版本、飞书文档密级标签(secure labels)和本地文件导入。用户需要整理云盘目录、处理云空间资源 URL/token、判断链接类型/真实 token/标题,或导入 Word/Markdown/Excel/CSV/PPTX/.base 为 docx/sheet/bitable/slides 时使用;doubao.com 云空间 URL/token 也按资源路径和 token 路由,不回退 WebFetch。不负责:文档内容编辑(走 lark-doc)、表格/Base 表内数据操作(走 lark-sheets/lark-base)、知识空间节点/成员管理(走 lark-wiki)、原生 Markdown 文件读写/patch/diff(走 lark-markdown)。
lark-shared
open.feishu.cn
Use for lark-cli setup/auth tasks: auth login/status/logout, user vs bot identity, business-domain permissions (--domain, including all/docs/drive), missing scopes, revoking authorization, or handling notice JSON.
lark-im
open.feishu.cn
飞书即时通讯:收发消息和管理群聊。发送和回复消息、搜索聊天记录、管理群聊成员、上传下载图片和文件、管理表情回复、发送应用内/短信/电话加急、发送和处理交互卡片(Interactive Card)、监听卡片按钮回调(card.action.trigger)。当用户需要发消息、查看或搜索聊天记录、下载聊天中的文件、查看群成员、搜索群、创建群聊或话题群、管理标记数据、管理 Feed 置顶(添加/移除/查询置顶会话)、管理标签数据、处理卡片回调时使用。