Skip to content

Releases

0.3.8 — wait for required fields

Choose a tag to compare

@FiredMosquito831 FiredMosquito831 released this 23 Oct 15:28
16d0d51

What was wrong

companies.get threw LAYOUT_UNSUPPORTED on a live company page even though the page renders completely. The reader required the company name immediately after navigation, before the page had rendered it: textOf with required: true took a single count, while the list readers already wait.

That single missing wait also caused a misdiagnosis: an early probe saw no <main> and no h1 and sent 0.3.7 after selector fallbacks that could never help. A probe with a four-second settle found main and exactly one h1, the company name.

What to expect now

  • Required single fields — the company name, the job title, and the job-page presence check — are retried for up to five seconds with the same bound and step the list readers use.
  • The first pass is immediate, so a page that already has the element adds no delay and every existing fixture behaves exactly as before.
  • The read still fails closed: if the field never appears, it throws LAYOUT_UNSUPPORTED after the bound.

Verified live on 2026-10-23

  • companies.get now parses and returns the company name on the page that failed in 0.3.7.
  • jobs.get keeps returning title and url.

Action required

None. npm i -g linkedin-api-mcp@0.3.8 or let the plugin pick it up.

Known and deliberate

  • Optional fields on the same pages (company followers, about) are still read once and immediately, so a field that renders after the name can be null.
  • A page that genuinely lacks the field now takes about five seconds to fail instead of about a tenth of a second.
  • parseJobCard still requires its title without a settle; list reads were out of scope.

by FiredMosquito831

0.3.7 — company pages and job titles

Choose a tag to compare

@FiredMosquito831 FiredMosquito831 released this 23 Oct 15:12

What was wrong

Two reads failed on the live site for measured reasons:

  • jobs.get looked for the job title in an h1, and the job page renders it as an h2 inside main.
  • companies.get required main h1, and the company page renders with no <main> element at all.

What to expect now

  • jobs.get finds the title from an h2 inside main, after the existing h1 candidates.
  • companies.get tries [role="main"] h1, then section h1, then a page-level h1, after main h1.
  • Both stay fail-closed: no heading, no name or title.

Verified live on 2026-10-23

  • jobs.get returned a populated record on a real job page: title present, url present. This part of the release works.
  • companies.get still returns LAYOUT_UNSUPPORTED. The company page has no h1 anywhere, so every h1-based candidate misses. The added fallbacks are correct for a page that has an h1, but they do not help this one.

Action required

None. npm i -g linkedin-api-mcp@0.3.7 or let the plugin pick it up.

Known and deliberate

  • companies.get remains unsupported on a live company page. The next step is to measure where the company name actually lives, not to add another fallback.
  • jobs.get still has no company field on the live page it was checked against.
  • The page-level h1 fallback takes the first h1 in document order; on a page whose site chrome has an h1 before the company name, the wrong name could be returned.

by FiredMosquito831

0.3.6 — company posts and people search

Choose a tag to compare

@FiredMosquito831 FiredMosquito831 released this 23 Oct 14:23
5400528

What was wrong

Two reads failed on every call:

  • companies.posts used the feed's post-card ladder. The company posts page renders no data-testid="mainFeed" and no reaction-controlled cards, so nothing matched even though the page shows posts.
  • search.people used the shared search ladder, which is job-only. People results render as listitem cards whose links are not /in/ links, so no row or title could match, and the unqualified main li hit the pagination control first.

What to expect now

  • companies.posts parses the main [role="article"] cards on a company posts page, appended after the existing ladder and wired only to this operation.
  • search.people parses main [role="listitem"] cards: the name as the title and the card's link as the url.
  • feed.list, posts.list, search.jobs and jobs.search are unchanged, proven byte-identical on fixtures.

Action required

None. npm i -g linkedin-api-mcp@0.3.6 or let the plugin pick it up.

Known and deliberate

  • Verified live on 2026-10-23: search.people returned 3 rows with a title and url on all 3. companies.posts returned 3 rows but only the text field — no title and no permalink. Treat company post records as partial.
  • The person name and headline candidates are structural (p elements), not measured markup; they resolved live on this account but are the most likely point of failure if LinkedIn changes the card.
  • Pagination exclusion assumes the pagination controls carry no role="listitem".

by FiredMosquito831

0.3.5 — live check covers every read

Choose a tag to compare

@FiredMosquito831 FiredMosquito831 released this 23 Oct 14:03
3b4a078

What was wrong

linkedin experimental live-check accepted only a fixed list of seven operation names. Everything else — search.companies, search.posts, analytics.profile-views, jobs.get, invitations.received and the rest — was rejected with "Unknown operation(s) … Live checks are read-only", even though the catalog knows they are reads. The one command that can verify an adapter against the real site therefore could not verify most adapters.

A second defect showed up while fixing the first: under --all-reads --url <company URL>, reads that need a different input shape were reported as failed (Failed: INVALID_INPUT). They were never attempted, so the report claimed a failure that had not happened.

What to expect now

  • --operations accepts any catalog read, not just the default seven.
  • --all-reads checks every catalog read, in catalog order.
  • An operation whose input does not match it, or that lacks its --url/--query, is reported as skipped, never as failed.
  • The default run is unchanged: same seven operations, same output, same navigation count.
  • --all-reads together with --operations is a validation error, not a silent preference.

Action required

None. npm i -g linkedin-api-mcp@0.3.5 or let the plugin pick it up.

Known and deliberate

  • --all-reads alone runs the 13 reads that need no target and skips the 20 that do. One --url and one --query are shared by every read that needs them, so a company URL is not also a post URL.
  • A skipped operation can hide an adapter that rejects a valid input. The skip line is the signal; the URL-family rule still lives in the adapter (resolveUrl), not in the catalog.
  • A full --all-reads run navigates the member's own account many times; run it deliberately, not on a schedule.
  • Nothing here was checked against live LinkedIn by the automated suite.

by FiredMosquito831

0.3.4 — search companies, search posts, and honest analytics errors

Choose a tag to compare

@FiredMosquito831 FiredMosquito831 released this 23 Oct 11:52
98e34c0

What was wrong

Two read surfaces failed on every query:

  • search.companies and search.posts returned LAYOUT_UNSUPPORTED. The search row ladder only knew job-card markup, so no company or post row could ever match. The title lookup is required, so even a matching row would have failed.
  • analytics.profile-views returned LAYOUT_UNSUPPORTED when LinkedIn redirected the request to /feed/. That redirect is an access gate, not a layout change, and misreporting it sent readers looking for a selector bug that did not exist.

What to expect now

  • search.companies returns company rows: the title comes from the company link, skipping the image-only logo link.
  • search.posts returns post rows that carry a reaction control — the same rule the feed reader uses — so suggested-people cards in the same list are excluded.
  • analytics.profile-views reports ACCESS_RESTRICTED (exit 4) with a message that says the page redirected away.
  • Every other operation keeps its previous behaviour on a route leave: LAYOUT_UNSUPPORTED.

Action required

None. npm i -g linkedin-api-mcp@0.3.4 or let the plugin pick it up.

Known and deliberate

  • The new candidates are proven on synthetic fixtures, not on live pages. A live experimental live-check is the next step; until it runs, treat the fix as unconfirmed on the real site.
  • search.people is still unsupported: its rows carry no anchors, so no row signature has been measured. It is left failing closed rather than guessed.
  • Post url and id still come from the first link in a row, which may be the author profile.
  • Verified against the registry: latest = 0.3.4, gitHead = 98e34c0, tarball SHA-512 equals dist.integrity, SLSA provenance present.

by FiredMosquito831

0.3.3 — visible challenges only

Choose a tag to compare

@FiredMosquito831 FiredMosquito831 released this 23 Oct 08:58
96909b2

What was wrong

A read-only company-page check reported HUMAN_INTERVENTION_REQUIRED on a page that returned HTTP 200, showed no verification prompt, and had no checkpoint route. The detector counted any matching element: every normal LinkedIn page carries a reCAPTCHA Enterprise anchor iframe that is 0×0, visibility:hidden, and inside a display:none ancestor. Counting it made ordinary pages look like challenges, which also made a live read pass stop early and be misreported.

What to expect now

  • A hidden background frame no longer stops an operation.
  • A visible challenge — or a visible dialog, alert, or heading with explicit verification wording — still stops the operation and reports HUMAN_INTERVENTION_REQUIRED.
  • Checkpoint routes and HTTP 401/403/429 still stop the operation, unchanged.
  • No frame is removed, disabled, entered, or solved. There is no bypass of any kind.

Action required

None. Upgrade with npm i -g linkedin-api-mcp@0.3.3 (or let the plugin's pinned version pick it up), then re-run linkedin experimental live-check if you had reads stopping on a challenge.

Known and deliberate

  • A challenge rendered inside an iframe whose host element stays 0×0 is caught by the verification-wording check rather than the frame check; the wording test is a heuristic.
  • Write adapters remain unverified live (0 of 21). Nothing about writes changed in this release.
  • Verified against the registry: latest = 0.3.3, gitHead = 96909b2, tarball SHA-512 equals dist.integrity, SLSA provenance present.

by FiredMosquito831

0.3.2 — live-verification fixes

Choose a tag to compare

@FiredMosquito831 FiredMosquito831 released this 22 Oct 19:01
37e3386

What changed

The browser adapters were verified against a real signed-in account for the first time. The live run showed that LinkedIn obfuscates its class names, so every class-based selector the adapters relied on was dead. This release moves them onto structural anchors and fixes what the real pages exposed.

Fixed

  • Obfuscated markup: selectors now key on data-testid, componentkey, data-job-id, roles and aria labels.
  • Feed accuracy: the feed list mixes posts with suggested people and ad cards. Only list items carrying a reaction control are treated as posts, and the author is read from the first profile link that renders a name.
  • Accessibility-tree gaps: some live controls are excluded from the accessibility tree, so role queries returned zero for a control that exists. Resolution now tries role, then aria label, then the attribute selector, after waiting for the control to render.
  • Connections route: /mynetwork/invite-connect/connections/.
  • Intermittent SPA 404: accepted only when the app shell actually renders.
  • Empty accounts: zero posts, conversations or connections now return an empty result instead of a layout failure.
  • Inbox rows: live rows are the thread links themselves; the new-message stub is excluded.
  • Outcome honesty: a verification challenge before dispatch reports AUTH_REQUIRED (exit 3), not an uncertain outcome (exit 8).

Added

  • approvals approve --yes removes the typed prompt while still requiring the exact reviewed digest.
  • OAuth login defaults to a registered HTTPS redirect, because LinkedIn rejects HTTP redirects.
  • Browser login waits for the session cookie when no terminal is attached.
  • HANDOFF-2026-10-22.md records the measured status.

Measured live status

Reads: 7 of 7 report ok. profile.get, feed.list, companies.get and jobs.search parse real data; posts.list, inbox.list and connections.list prove the empty-account path only.

Writes: none verified live. The first attempts at companies.follow were interrupted by a LinkedIn manual-verification challenge and changed nothing. Write adapters remain fixture-tested; do not run them in bulk.

Upgrade

npm install -g linkedin-api-mcp@0.3.2