Skip to content

Commit cc34ed4

Browse files
committed
feat: initial LinkedIn adapter for browserkit
7 tools: get_person_profile, get_company_profile, get_company_posts, search_people, search_jobs, get_job_details, get_feed. Uses innerText extraction strategy (resilient to LinkedIn DOM churn) and walks up from ARIA-labelled action buttons for feed post detection. Made-with: Cursor
0 parents  commit cc34ed4

13 files changed

Lines changed: 1752 additions & 0 deletions

.github/workflows/ci.yml

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
jobs:
10+
test:
11+
name: Build & Test
12+
runs-on: ubuntu-latest
13+
14+
steps:
15+
- uses: actions/checkout@v4
16+
with:
17+
path: adapter-linkedin
18+
19+
- uses: actions/checkout@v4
20+
with:
21+
repository: browserkit-dev/browserkit
22+
path: browserkit
23+
24+
- uses: actions/setup-node@v4
25+
with:
26+
node-version: 20
27+
28+
- name: Install & build @browserkit/core
29+
working-directory: browserkit
30+
run: |
31+
npm install -g pnpm
32+
pnpm install --frozen-lockfile
33+
pnpm --filter @browserkit/core build
34+
35+
- name: Patch @browserkit/core dep path
36+
working-directory: adapter-linkedin
37+
run: |
38+
npm pkg set 'devDependencies.@browserkit/core'='file:../browserkit/packages/core'
39+
npm pkg set 'peerDependencies.@browserkit/core'='>=0.1.0'
40+
41+
- name: Install adapter dependencies
42+
working-directory: adapter-linkedin
43+
run: npm install
44+
45+
- name: Install Patchright Chromium
46+
working-directory: adapter-linkedin
47+
run: npx patchright install chromium --with-deps
48+
49+
- name: Build
50+
working-directory: adapter-linkedin
51+
run: npm run build
52+
53+
# Unit tests only — integration tests require a live authenticated LinkedIn session
54+
- name: Test
55+
working-directory: adapter-linkedin
56+
run: npm test
57+
timeout-minutes: 10

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
node_modules/
2+
dist/
3+
.DS_Store
4+
*.storage-state.json

README.md

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# @browserkit/adapter-linkedin
2+
3+
[LinkedIn](https://www.linkedin.com) adapter for [browserkit](https://github.com/browserkit-dev/browserkit) — exposes LinkedIn as MCP tools over your authenticated local browser session. Runs entirely on your machine; no credentials leave localhost.
4+
5+
## Tools
6+
7+
| Tool | Key inputs | Description |
8+
|---|---|---|
9+
| `get_person_profile` | `linkedin_username`, `sections?` | Scrape a person's profile. Optional sections: `experience`, `education`, `interests`, `honors`, `languages`, `contact_info`, `posts` |
10+
| `get_company_profile` | `company_id`, `sections?` | Scrape a company page. Optional sections: `about`, `jobs`, `people`, `insights` |
11+
| `get_company_posts` | `company_id`, `count?` | Recent posts from a company page |
12+
| `search_people` | `keywords`, `count?` | Search LinkedIn people |
13+
| `search_jobs` | `keywords`, `location?`, `count?` | Search LinkedIn job listings |
14+
| `get_job_details` | `job_id` | Full details for a specific job posting |
15+
| `get_feed` | `count?` | Your personalised LinkedIn feed |
16+
17+
Plus auto-registered management tools from the framework: `browser` (health check, screenshot, page state, mode switch, navigate), `close_session`.
18+
19+
## Setup
20+
21+
```bash
22+
# Install
23+
pnpm add @browserkit/adapter-linkedin
24+
25+
# One-time login (opens a browser window — sign in normally)
26+
browserkit login linkedin
27+
28+
# Start
29+
browserkit start --config browserkit.config.js
30+
```
31+
32+
```js
33+
// browserkit.config.js
34+
import { defineConfig } from "@browserkit/core";
35+
36+
export default defineConfig({
37+
adapters: {
38+
"@browserkit/adapter-linkedin": {
39+
port: 3848,
40+
channel: "chrome", // use real Chrome — avoids bot detection on login
41+
},
42+
},
43+
});
44+
```
45+
46+
Connect your MCP client (Cursor, Claude Desktop, etc.) to `http://127.0.0.1:3848/mcp`.
47+
48+
## How it works
49+
50+
LinkedIn's DOM changes frequently. This adapter uses an **`innerText` extraction strategy** rather than CSS class selectors: it navigates directly to section URLs and reads raw text content. This makes it resilient to React component upgrades and class-name churn.
51+
52+
For the feed tool, post cards are located by walking up from their social action buttons (`aria-label` containing "like"/"comment"/"repost") — stable semantic anchors that don't rotate.
53+
54+
Auth uses a persistent browser profile (`~/Library/Application Support/browserkit/profiles/linkedin` on macOS). Cookies survive daemon restarts — you only need to `browserkit login linkedin` once.
55+
56+
## Session notes
57+
58+
- Use `channel: "chrome"` in your adapter config to use real Google Chrome. This avoids LinkedIn's bot detection on the login page.
59+
- The adapter runs headless by default. Use the `browser` MCP tool with `action: "set_mode"` and `mode: "watch"` to make it visible for debugging.
60+
- Rate limit is 3 seconds between tool calls by default to avoid triggering LinkedIn's anti-scraping measures.
61+
62+
## Tests
63+
64+
```bash
65+
pnpm test # unit tests (schema, scraper logic, URL building)
66+
pnpm test:integration # live browser tests against real LinkedIn (requires login)
67+
```
68+
69+
## License
70+
71+
MIT

package.json

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"name": "@browserkit/adapter-linkedin",
3+
"version": "0.1.0",
4+
"description": "LinkedIn adapter for browserkit — profile, company, jobs, people search, and feed",
5+
"type": "module",
6+
"main": "./dist/index.js",
7+
"types": "./dist/index.d.ts",
8+
"exports": { ".": { "import": "./dist/index.js", "types": "./dist/index.d.ts" } },
9+
"scripts": {
10+
"build": "tsc",
11+
"test": "vitest run",
12+
"test:integration": "vitest run --config vitest.integration.config.ts",
13+
"lint": "tsc --noEmit"
14+
},
15+
"peerDependencies": {
16+
"@browserkit/core": ">=0.1.0"
17+
},
18+
"devDependencies": {
19+
"@browserkit/core": "github:browserkit-dev/browserkit#main",
20+
"@types/node": "^22.13.14",
21+
"patchright": "^1.51.1",
22+
"tsx": "^4.19.3",
23+
"typescript": "^5.7.3",
24+
"vitest": "^3.0.9",
25+
"zod": "^3.24.2"
26+
},
27+
"engines": {
28+
"node": ">=20"
29+
}
30+
}

0 commit comments

Comments
 (0)