Skip to content

[FEATURE] Add search_posts tool for global LinkedIn post/content search #531

Description

@AkaNebur

Feature Description

Add a new read-only MCP tool search_posts(keywords, date_posted=None, max_pages=3) that runs
LinkedIn's global "Posts" content search (the /search/results/content/ surface) and returns
the matching posts. An optional date_posted recency filter (past-24h / past-week /
past-month) maps onto LinkedIn's datePosted facet. Results come back in the project's canonical
{url, sections, references?, section_errors?} shape — raw innerText for the LLM to parse, plus
feed_post permalink references.

This is distinct from the two post-related tools that already exist:

  • get_feed — only the authenticated user's home feed
  • get_company_posts — only one company's page

Neither can search posts globally by keyword, which is the gap this tool fills.

Use Case

Global keyword search over LinkedIn posts lets an agent discover content by topic across all of
LinkedIn rather than just feeds it already follows. The concrete driver: catching informal hiring
posts
— "we're hiring", "Buscamos …", "estamos contratando", "join our team" — that frequently
appear in post/content search before a formal job listing is published, giving earlier signal than
search_jobs. More generally it enables monitoring announcements, product launches, or any topic by
keyword, optionally scoped to the last 24h / week / month.

Suggested Approach

Mirror the existing search-tool conventions:

  • Add LinkedInExtractor.search_posts plus a pure @staticmethod _build_content_search_url that
    composes /search/results/content/?keywords=...&origin=FACETED_SEARCH and appends the datePosted
    facet as a URL-encoded one-element JSON list via the existing _encode_list_facet helper — the same
    way search_people encodes its network / currentCompany facets (content search uses literal
    datePosted tokens rather than job search's f_TPR=r<seconds> codes). Validate date_posted
    against a _CONTENT_DATE_POSTED_MAP, raising FilterValidationError on bad input.
  • Content search is an infinite scroll with no &start= pagination, so map max_pages to scroll
    depth (~5 scrolls/page) and reuse extract_page.
  • Return the canonical {url, sections, references?, section_errors?} shape; surface raw innerText
    plus feed_post permalinks. No structured per-post objects — same rationale as get_feed (no
    stable, locale-independent selector), consistent with the AGENTS.md scraping philosophy.
  • A thin tools/post.py:register_post_tools wrapper wired into server.py, plus the "Adding a New
    Tool" checklist surfaces (README, manifest.json, docs/docker-hub.md, tools/init.py) and
    two-layer tests in test_scraping.py / test_tools.py.

I have a working implementation (unit-tested and verified live against real LinkedIn) and will open a
PR referencing this issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions