---
name: linkedin-extension
description: "One-click LinkedIn ingest. Ships a manifest-v3 Chrome extension that injects an Add-to-Real Agent pill into `linkedin.com/in/*` profiles and `linkedin.com/messaging/thread/*` DM threads. Each click scrapes the page DOM, POSTs to the admin `linkedin-ingest` route, which dispatches `database-operator` against the generic `document-ingest` skill. The plugin is the **first consumer** of the generic communication-ingest path; every future communication surface (email, Telegram, WhatsApp, group chats, voice memos) plugs into the same backend. Opt-in per brand."
tools: []
always: false
embed: false
specialist: database-operator
metadata: {"platform":{"optional":true,"pluginKey":"linkedin-extension"}}
---

# LinkedIn Extension

Capturing a LinkedIn lead today costs 30-90 seconds per record. This plugin replaces that with one click. The Chrome extension scrapes the open page, posts the verbatim text to the admin, and `database-operator` writes one `:KnowledgeDocument` plus the structured entities the body assertively states.

## Two surfaces

| URL pattern | What gets captured |
|---|---|
| `linkedin.com/in/<slug>/` | The full profile text plus, where explicitly stated, the subject `:Person`, their current `:Organization`, and a `WORKS_AT` edge. |
| `linkedin.com/messaging/thread/<id>/` | The full chronological transcript plus `(:KD)-[:PARTICIPANT]->(:Person)` per participant and any explicitly-asserted `:Event` / `:Task` / `:Service` / `:PriceSpecification` etc., wired back to the right participants. |

Re-clicking the same URL refreshes the KD body and regenerates the summary. Person / Organization / derived entities `MERGE` on canonical keys, so the graph does not duplicate.

## Architecture

```
Chrome extension                    Hono admin                Specialist
─────────────────                    ──────────                ──────────
content/profile.js  ──POST──>  /api/admin/linkedin-ingest  ──>  database-operator
content/thread.js                      requireAdminSession        document-ingest skill
                                       schema validate            memory-ingest tools
                                       spawn database-operator    graph writes
```

The route's job is auth + schema + dispatch. Extraction logic lives in `document-ingest`; ontology decisions live in the schema reference. The extension is the only LinkedIn-bespoke part.

## Files

- `extension/manifest.json` — manifest v3
- `extension/content/profile.js` — content script for `linkedin.com/in/*`
- `extension/content/thread.js` — content script for `linkedin.com/messaging/thread/*`
- `extension/background/sw.js` — service worker handling POSTs
- `extension/options/options.{html,js}` — admin host + bearer token entry
- `extension/assets/pill.css` — pill styling
- `extension/README.md` — developer install guide
- `extension/__tests__/{profile,thread}.test.ts` — jsdom extractor tests
- `extension/__tests__/fixtures/{profile,thread}.html` — frozen DOM fixtures captured 2026-05-22
- `skills/linkedin-extension/SKILL.md` — payload schema + DOM-selector rules

## Sibling plugins

- `linkedin-import` — consumes a LinkedIn ZIP export (bulk historical). Different surface; both ship.
- `memory.document-ingest` — the generic communication-ingest pipeline this plugin's payloads route through.
- `contacts` — `:Person` nodes minted here surface in `contact-list` like any other.

## Enabling

Add `linkedin-extension` to a brand's `enabledPlugins` in `brand.json`. Default brands ship without it.
