Scrape service-provider search
One page of LinkedIn’s service-provider marketplace (freelancers and agencies), addressed EITHER by filters (keywords, LinkedIn’s own numeric service-category and geo ids, connection degree, profile language) OR by a pasted /search/results/services/ url, which is how to reach anything those five cannot express: exactly one of the two. Rows are the same person previews the people search returns, because the services screen carries no ratings and no service labels in its results, only provider profiles.
Contract:
- MCP tool
scrape_linkedin_search_service_providers, registry packagemcp.linkedin/linkedin_scraping, mountlinkedin.scraping. - Operation
action, response envelopeaction. - Flags: none.
Authorizations
Access token issued by gtm.service.id. Its access_identity claim carries team_sid, actor_sid and actor_type, and that team scope is authoritative.
Team scope for tokens that do not carry one. Ignored when the token already names a team.
Body
Request body of scrape_linkedin_search_service_providers.
Executor account (ln_ac_...). OPTIONAL everywhere on this surface. Given: the call runs on that account ONLY; a saturated or held scraping bucket refuses 429 bucket_saturated (with retry_after). Omitted: the service auto-picks one of your connected accounts with remaining capacity (SN verbs pick only Sales-Navigator seats; 422 no_connected_accounts when none is ready, 429 when all are at capacity).
18^ln_ac_Ledger replay guard: a repeat call with the same (team, key) returns the stored outcome; no re-execution. Recommended on every search run. The KEY ALONE decides: the probe does not compare arguments, so reusing one key after changing the arguments hands back the FIRST result. On the twelve search verbs that matters twice over, because switching a call from filters to url (or back) under one key replays instead of running the new search. New search, new key.
128EXCLUSIVE with filters: send url OR filters, never both (422) and never neither (422). A search URL built in the LinkedIn UI, and the escape hatch for everything the filter vocabulary cannot express. MUST start with https://www.linkedin.com/search/results/services/ : a URL from another LinkedIn search screen is refused here and again by the backend (422 invalid_search_url), because running it would silently scrape the wrong thing.
2048^https:\/\/www\.linkedin\.com\/search\/results\/services\/EXCLUSIVE with url: send filters OR url, never both (422) and never neither (422). Service-provider marketplace filters. At least one member must be non-empty. Anything these five cannot express is reachable by pasting the UI URL into this tool's own url field instead.
LinkedIn page number, default 1; ONE page per call, so re-call with page + 1 while paging.has_more.
1 <= x <= 100