linkedin-mcp
linkedin-mcp
実際の Chromium ブラウザ上で、あなた自身がログインした LinkedIn セッションを操作し、すべての書き込み操作の前に明示的な確認ステップを挟む Model Context Protocol サーバーです。
お️ まず読んでください
これは通常の API クライアントではありません。インストールする前に、以全を読んでください。
あなたに代わり、実際にログイン済みのブラウザセッションを操作します。 サーバーは Chromium を起動し、保存されている LinkedIn クキーを復元し、人間がクリックするのと同じボタンをクリックします。
正規の LinkedIn API は使っていません。 その背にOAuthアプリもパートナー契約も、サポートされた連携もありません。これは公開 Web サイトのブラウザ自動操作です。
この方法での LinkedIn の自動化は、LinkedIn のユーザー規約の外で行われます。 LinkedIn の規約は、スクレイピングと自動アクセスを禁止しています。
あなたのアカウントは、レート制限・制限または永久的な停止を受ける可能性があります。 そのリスクは現実的であり、仮定の話ではありません。LinkedIn は自動化を検知し、執行は予告なく、不服申し立てもできないまま行われ得ますます。
あなたのセションクキーはこのマシン上にあります。 ログインが成功すると、Playwright の
storageStateファイルがローカルディスクに書き込まれます。このファイルを読める人は誰でも、あなたとして LinkedIn を操作できます。利用は完全にアカウント所有者自身の責任で行われます。 ここに明示保証も黙示保証も一切ありませんし、アカウントが停止された場合の救済手段もありません。
以上の3つの設計上の判断は上記の事実から導かれており、設定では変更できません。
単一のアカウント、単一のユーザー。 サーバーは保存した一つのセッションを保持する一つの状態ディレクトリを持ちます。マルチアカウントのサポートも「ユーザー」の概念もありません。キーボードの前の人のためのローカルツールです。
すべての書き込み操作には明示的な確認が必須です。 投稿、接続、メッセージ、求人への応募は、すベて2回の呼び出しによるハンドシェイクです。1回のツール呼びだけでLinkedInに何かを送信することはありません。次のセクションを参照してください。
サーバーは CAPCHA を絶対に解決しません。 パスワードも打、ちません。2FAのプロンプトを消ませんし、セキュリティチェックポイトを回避しません。LinkedInがチャレンジを出すとき、サーバーは停止し、通常のブラウザで自分で処理するよう求めます。
上記のいずれかがアカウントにとって受け入れられない場合、インストールしないでください。
Related MCP server: LinkedIn MCP Server
確認してから実行す仕組み
書き込み系のツール(linkedin_create_post、linkedin_send_connt_request、linkedin_send_messge、linkedin_apply_to_ob)はすべて、2回呼び出しのハンドシェイクです。
呼び出し1 — プレビュー。 実際の引数で、confirm をなしでツールを呼び出します。サーバーはページを調査し、実際に何が起こるかを正確に特定して、プレビューエンベロープを返します。何も送盾されず、日割のクォータも消費されません。
{
"profileUrl": "https://www.linkedin.com/in/dana-whitfield-example/",
"note": "Hi Dana — we both worked on the OpenTelemetry collector. Would like to connect."
}呼び出し2 — 確認。 同じ呼び出しに confirm: true を含めてもう一度実行します。任意で、受け取た previewToken を返してもよいです。しておくと、サーバーはプレビュー時から引数が変っていないこを検証し、変わっていれば confirmation_mismatch で失敗します。
{
"profileUrl": "https://www.linkedin.com/in/dana-whitfield-example/",
"note": "Hi Dana — we both worked on the OpenTelemetry collector. Would like to connect.",
"previewToken": "9f2c41ab77e05d13",
"confirm": true
}プレビューエンベロープは次のようになります(実際の linkedin_send_connection_request プレビュー):
{
"status": "preview",
"action": "linkedin_send_connection_request",
"executed": false,
"confirmationRequired": true,
"summary": {
"profileUrl": "https://www.linkedin.com/in/dana-whitfield-example/",
"name": "Dana Whitfield",
"headline": "Staff Engineer, Observability",
"note": "Hi Dana — we both worked on the OpenTelemetry collector. Would like to connect.",
"noteLength": 88,
"notePreview": "Hi Dana — we both worked on the OpenTelemetry collector. Would like to connect.",
"connectionDegree": 2,
"connectionDegreeLabel": "2nd",
"connectPathway": "direct",
"alreadyPending": false,
"wouldSucceed": true
},
"previewToken": "9f2c41ab77e05d13",
"quota": {
"action": "connectionRequests",
"used": 3,
"cap": 20,
"remaining": 17,
"resetsAt": "2026-08-25T07:00:00.000Z",
"allowed": true
},
"warnings": [],
"howToConfirm": "Nothing has been sent to LinkedIn yet. To execute, re-issue the exact same `linkedin_send_connection_request` call with `confirm: true` (optionally echoing `previewToken: \"9f2c41ab77e05d13\"` so the arguments are verified as unchanged)."
}プレビューの読み方:
executed: falseとconfirmationRequired: trueは、プレビューでは常に存在します。実行済みの結果には代わりに"status": "executed"、executed: true、resultオブジェクトが含まれます。warningsは、サせーが問題を感じているとこを伝える場所です。トランケーとされた投稿、長すぎる接続のメ、消費しきったクォータ、dry-runート、など。プレビューで呼び出しが成功しない(すでに1次つながりの関係、すでにペンディングの招待が存在、Connect コントローがない、1次つながではないなど)と示されている場合、
howToConfirmにはその旨が明記され、sure 認を指定してもinvalid_inputで拒否され、クォータは消費されません。previewTokenは、アクション名と正規格化されたペイロードに対する短いダイジェストです。これは不一致防止のためのガドであって、セキュリティトークンではありません。
必要環節
Node.js 20以上 (
"engines": { "node": ">=20" })。可視なブラウザウィンドウを開けるデスクトップ環境。インタラクティブなログインにはこれが必要です。
Playright の Chromeium ビルド(下記参照)。
セットアップ
依存関係をインストールします:
npm installPlaywright が使う Chromium ビルドをダウンロードします:
npx playwright install chromium環境フaイルを作成します(中の変数はすべてオプションで、認証情報は含まれません):
cp .env.example .env設定フファイルを作成します(日々の上限とタイムアウトのみ):
cp config.example.json config.jsonTypeScriptを dist/ にコンパイルします:
npm run build初回時の手順
この手順により、最後のステップまではLinkedInアカウントに一切触れません。
npm installnpx playwright install chromiumcp .env.example .envとcp config.example.json config.json— どちらもオプションで、クレデンシャルは含まれませんnpm run buildnpm test— 75件の本体ユニットテスト。ブラウザもネットワークも不要ですnpm run verify:dry— ローカルのフィクスチャーに対し、すべての11ツールを動かし、アカウントを向けた前に配線が正しいことを確認します (詳細argsにまず--dry-runを含め、MCP クライアントにサーバーを登録します (詳細。クライアントに 11ツールが表示され、書き込みツールがプレビューを返すことを確認します。argsから--dry-runを外し、クライアントを再起動してlinkedin_loginを呼びます ([詳細](detail #details?))。これが、じめて linkedin.com にアセスするステップです。可視の Chromium ウンドウが開き、あなた自身が手でサインインします。linkedin_session_statusを呼び出し、保存したセションが正しく動くことを確認します。
ステップ 8 が境界です。それ以前はすべて、ディレクトリを削除することで元に戻せます。
ログイン
このプロジェクトには、認証情報の設定はどこにもありません。それ意図的です。実際のブラウザウインドウで、一度だけ手動でサインインします。
linkedin_loginツールを呼びます。引数はありません。実際の可視な Chromium ウインドウが LinkedIn のログインページに開きます。
headless: trueを設定しても表示されます。インラクティブなログインでは常にヘッド付きブラウザが強制されます。あなたがメールアドレスとパスワードを入力し、あなたが LinkedIn が次に求るもの(SMSコード、ユチケータコー、メール PIN、デバイス続認、CAPTCHA)を解除します。サーバーは認証情報を入力しませ型、パフィールドを読み取りません。チャレンジのウィジェトに触れることもありません。ただ2秒ごとにポールし、LinkedIn のナビゲションにサインイン済みの本人要素が現れるのを待ちます。
急がなくて大丈夫です。待機時間は
loginTimeoutMsで制限され、デフォルトは300000(5分)です。今回必要ならconfig.jsonで上げてください。LinkedIn がサインイン済みフィードを表示したら、ブラウザセションは状態ディレクトリの
storageState.jsonに書込まれます(ファイル権限は0600=所有者の読み書きのみ)。このファイルは gitignore されます。以降のツール呼び出しはその保存済みセションを再利用します。数週間は再度ングイン不要です。
linkedin_session_status(引数なし)でいつでもセションを確認できます。フィードを1回読み込んで、次を報告します:
{
"valid": true,
"lastVerified": "2026-08-24T18:42:10.114Z",
"sessionSavedAt": "2026-08-11T09:03:55.002Z"
}valid: false の場合、reason も返します(例えば LinkedIn がフィードをサインインページにリダレクトしたこと)。クキーやセションの内容が、このツールまたは他のいかなるツールによって返されることはありません。
セションには有効期限があります。 期限が切れると、ツールは session_expired で失敗します。対策は常に同じです: linkedin_login をもう一度実行し、手操作でサインインします。
レート制限・ペーシング
サーバーは独自の日次上限を適用し、ブラウザ操作の前にランダムな遅延を入れます。これはアカウントを守る上で最も重要な保護であり、デフォルトは意図的に控えめです。
config.example.json を config.json にコピーして編集してください:
{
"dailyCaps": {
"connectionRequests": 20,
"messages": 30,
"posts": 5,
"jobApplications": 10
},
"delayRangeMs": {
"min": 1500,
"max": 6000
},
"headless": false,
"navigationTimeoutMs": 30000,
"actionTimeoutMs": 15000,
"loginTimeoutMs": 300000
}四つの日次上限
上限 | 制限内容 | デフォルト |
|
| 20 / 日 |
|
| 30 / 日 |
|
| 5 / 日 |
|
| 10 / 日 |
動作は次のとおりです:
上限は、確認済みの実行時のみ消費できます。プレビューは現在のクォータを報告しますが、消費はしません。サーバーが完全に拒否した呼び出しは消費しません。
カウントは状態ディレクトリの
counters.jsonに保存されるため、サーバーを再起動してもリセ不是れません。上限に達したときは、実行されずに
rate_limitedで失敗します。上限を0にすると、そのアクション自体を無効にします。すべてのプレビューと実行済エンべロープには、
used・cap・remaining・resetsAt・allowedを持つquotaブロックが含まれます。
ランダム間延
delayRangeMs は、ブラウザのアクションの前にサーバーが均一にランダムに待機する範囲です — デフォルトは 1500 ms から 6000 ms。ランダム化は重要です。固定の間隔は機械の指紋になります。min は max と等しくても構い(固定遅延)ず、min が max を超えると configロードが config_invalid で失敗します。
上限はローカルの深夜にリセット
カウンタはローカルのカレンダー日付でキー付けされるため、四つの上限はあなたのタイムゾーンの深夜にリセットされます — UTC の深夜ではなく、ローリング 24 時間ではありません。quota の resetsAt は、次のローカル深夜を UTC ISO タイムスタンプとして表したものです。
グデフォルトより低い上限から始める
デフォルトで出荷される値は上限であって、推奨ではありません。アカウントが新しい、コネクションがまだ少ない、またはオートメーションを使うのが初めてなら、十分に低い値から始めてください — 例えば connectionRequests: 5、messages: 5、posts: 1、jobApplications: 2 — そして、LinkedIn の警告に注意しながら数週間かけてゆっくり上げます。
ツール・リファレンス
11のツールを、サーバーが登録する順に示します。
これらの4つのスクレーピング/求人ツール(linkedin_scrape_profile、linkedin_scrape_feed、linkedin_search_jobs、linkedin_apply_to_job)は、src/types.ts と src/selectors.ts の共通コントラクトから説明されています。使用しているクライアントの tools/list 出力がここでの引数名と異なる場合は、tools/list が正です — 実際のスキーマをサーバーが報告します。
linkedin_login
実表示の Chromium ウィンドウを開き、2FAやCAPTCHAを含めて、あなたが自分でサインインするのを待機します。成功するとセッションをローカル・ディスクに保存します。引数はありません。--dry-run では使用できません。
{}linkedin_session_status
保存セッションがまだ機能するか、いつ保存されたか、いつ実行確認されたかを報告します。1回フィードを読んでチェックします。読み取りのみ。--dry-run では常に valid を報告します。引数はありません。
{}linkedin_create_службы (書き込み — 確認が必要)
自分フィードにテキストを投稿します。posts 上限を使いいます。
プレビュー:
{
"text": "Spent the week reading Playwright's tracing internals. Notes soon.",
"visibility": "connections"
}確認:
{
"text": "Spent the week reading Playwright's tracing internals. Notes soon.",
"visibility": "connections",
"confirm": true
}text— 必須、1〜3000文字。約1300字を超えると LinkedIn は投稿を「see more」で折りたたみます。プレビューで警告します。visibility— 任意、"public"または"connections"。デフォルトは"public"。mediaUrl— 任意の URL です。サーバーはリンク先のメディアを取り込むことはありません。 指定するとプレビューで警告し、事項確認ではinvalid_inputで拒否します。previewToken— 任意。送信すると、引数がユーザーの内容と変わっていないかを検証します。confirm— 任意のブーアン。実行するには完全にeuである必要があります。
linkedin_send_conton_request(書き込み — 確認が必要)
接続の招待を、オプションで note を添付して送信します。connectionRequests の制限を消費します。
本ビュー:
{
"profileUrl": "https://www.linkedin.com/in/dana-whitfield-example/",
"note": "Hi Dana — we both worked on the OpenTelemetry collector. Would like to connect."
}確認:
{
"profileUrl": "https://www.linkedin.com/in/dana-whitfield-example/",
"note": "Hi Dana — we both worked on the OpenTelemetry collector. Would like to connect.",
"previewToken": "9f2c41ab77e05d13",
"confirm": true
}profileUrl— 必須、空外をしません。完全なプロフィル URL またはベアなバニティスラグです。note— 任意、最大300字。200字を超えるノートはの多くのアカウントで LinkedIn のプレミアムが必要になります。200超え場合はプレビューが警告します。previewToken/confirm— 上と同。
すでに1次つながりの関係がある場、招待が進行中である場、そのページーに Connect コントロールがない場合は、クォータを消費す前に invalid_input で拒否されます。
linkedin_send_message(書き込み — 確認が必要)
Sends a direct message. Consumes the messages cap.
ダイレクトメッセージを送信します。messages キャップを消費します。
プレビュー:
{
"profileUrlOrConversationId": "https://www.linkedin.com/in/dana-whitfield-example/",
"text": "Thanks for the pointer to the collector RFC — that answered my question."
}確認:
{
"profileUrlOrConversationId": "https://www.linkedin.com/in/dana-whitfield-example/",
"text": "Thanks for the pointer to the collector RFC — that answered my question.",
"confirm": true
}profileUrlOrConversationId— 必須、空にできません。プロフィールURL/スラッグ、または既存の会話スレッドID(/messaging/thread/<id>/形式)のいずれか。text— 必須、1〜8000文字。previewToken、confirm— 上記と同じ。
プロフィールモードでは、受信者は1次のつながりである必要があります。それ以外の相手は、割り当てを消費する前に not_connected で拒否されます。このツールはInMailを送信せず、作成ボックスでEnterキーを押すこともありません — Sendボタンをクリックします。
linkedin_scrape_profile
1つのプロフィールを読み取り、構造化された Profile を返します:名前、見出し、概要、場所、つながりの次数、自分のプロフィールかどうか、経験エントリ、学歴エントリ、スキル。読み取り専用。
{
"profileUrl": "https://www.linkedin.com/in/dana-whitfield-example/"
}linkedin_scrape_feed
フィードから最近の投稿を読み取り、FeedPost エントリを返します:著者名と見出し、テキスト、投稿URL、いいね数とコメント数、投稿日時。読み取り専用。
{
"count": 20
}linkedin_search_jobs
LinkedInの求人検索を実行し、JobListing エントリを返します:jobId、タイトル、会社、場所、Easy Applyかどうか、求人URL。読み取り専用。
{
"keywords": "site reliability engineer",
"location": "Berlin, Germany",
"easyApplyOnly": true,
"count": 25
}keywords は必須です。その他はすべてオプション:
location— 自由記述の場所名。LinkedIn自身のlocationパラメータにマッピングされます。easyApplyOnly— 結果をEasy Applyの求人に限定します(LinkedInのf_ALファセット)。linkedin_apply_to_jobはEasy Applyのみを処理するため、このサーバーを通じて応募する予定がある場合は常に設定する価値があります。datePosted—"past24h"、"pastWeek"、または"pastMonth"。experienceLevel—"internship"、"entry"、"associate"、"midSenior"、"director"、または"executive"。remote—trueにすると、結果がリモート勤務の職種に限定されます。count— 返す求人の数(デフォルト25、最大100)。結果は遅延読み込みされるため、countが大きいと、それぞれの間にランダムな一時停止を挟んだスクロールが繰り返され、時間がかかることがあります。
これらの4つのファセットは、上記のようにトップレベルで渡すか、filters オブジェクト内にグループ化して渡すことができます — どちらも受け付けられ、同じキーを2回渡した場合は filters が優先されます:
{
"keywords": "site reliability engineer",
"filters": { "easyApplyOnly": true, "datePosted": "pastWeek", "remote": true },
"count": 50
}LinkedInが使用可能なジョブIDなしでレンダリングするカード(プロモーション枠、プレースホルダー)は、不完全な状態で返されるのではなくスキップされ、レスポンスの skipped フィールドにカウントされます。レスポンスは使用した searchUrl もエコーバックするため、同じクエリを自分のブラウザで開くことができます。
linkedin_apply_to_job(書き込み — 確認が必要)
LinkedInのEasy Apply申請を送信します。jobApplications キャップを消費します。
プレビュー:
{
"jobId": "3912847561",
"resumePath": "/Users/parthbansal/Documents/resume.pdf"
}確認:
{
"jobId": "3912847561",
"resumePath": "/Users/parthbansal/Documents/resume.pdf",
"confirm": true
}jobId— 必須。生のジョブID、/jobs/view/<id>/URL、?currentJobId=を含む検索URL、またはジョブURNはすべて同じIDに解決されます。resumePath— このマシン上の履歴書ファイルへのオプションの絶対パス。ファイルがない場合はfile_not_foundで失敗します。ファイルの内容がログに記録されることはありません。外部の応募者追跡システムに引き渡す求人は
external_applicationで失敗します。Easy Applyコントロールのない求人はnot_easy_applyで失敗します。確認する前にプレビューを読んでください — フォームがあなたに代わって回答しようとしている質問を確認できる唯一の機会です。previewToken、confirm— 上記と同じ。
linkedin_list_pending_invites
保留中の招待を PendingInvite エントリとして一覧表示します:名前、見出し、プロフィールURL、送信日時、方向。読み取り専用。
{
"direction": "received",
"count": 25
}direction— オプション。"received"(誰かがあなたを招待)または"sent"(あなたが相手を招待)。デフォルトは"received"。count— オプションの整数、1〜100。デフォルトは25。
linkedin_list_connections
自分のつながりを ConnectionSummary エントリとして一覧表示します:名前、見出し、プロフィールURL、つながった日時。読み取り専用。
{
"count": 50,
"query": "observability"
}count— オプションの整数、1〜200。デフォルトは50。query— オプション。サーバーがすでに読み取ったつながりに適用されるローカルな大文字小文字を区別しない部分文字列フィルターです。検索としてLinkedInに送信されることはありません。
MCPクライアント設定
サーバーはstdio上でJSON-RPCを使用し、手動ではなくMCPクライアントによって起動されることを想定しています。まずビルドし(npm run build)、その後クライアントを dist/server.js に向けます。
サーバーは config.json、状態ディレクトリ、fixtures/ をその作業ディレクトリからの相対パスで解決するため — そしてMCPクライアントの作業ディレクトリは通常このプロジェクトではないため — env ブロックで絶対パスを明示的に設定する価値があります。
Claude Code / Claude Desktop
claude_desktop_config.json 内:
{
"mcpServers": {
"linkedin": {
"command": "node",
"args": ["/Users/parthbansal/Desktop/claude code/linkedin-mcp/dist/server.js"],
"env": {
"LINKEDIN_MCP_CONFIG": "/Users/parthbansal/Desktop/claude code/linkedin-mcp/config.json",
"LINKEDIN_MCP_STATE_DIR": "/Users/parthbansal/Desktop/claude code/linkedin-mcp/.linkedin-mcp",
"LINKEDIN_MCP_LOG_LEVEL": "info"
}
}
}
}Cursor
.cursor/mcp.json 内:
{
"mcpServers": {
"linkedin": {
"command": "node",
"args": ["/Users/parthbansal/Desktop/claude code/linkedin-mcp/dist/server.js"],
"env": {
"LINKEDIN_MCP_CONFIG": "/Users/parthbansal/Desktop/claude code/linkedin-mcp/config.json",
"LINKEDIN_MCP_STATE_DIR": "/Users/parthbansal/Desktop/claude code/linkedin-mcp/.linkedin-mcp",
"LINKEDIN_MCP_LOG_LEVEL": "info"
}
}
}
}汎用stdioクライアント(例:Codex CLI)
stdio MCPサーバーを起動するクライアントには、同じ3つのものが必要です — コマンド、その引数、環境:
{
"name": "linkedin",
"command": "node",
"args": ["/Users/parthbansal/Desktop/claude code/linkedin-mcp/dist/server.js"],
"env": {
"LINKEDIN_MCP_CONFIG": "/Users/parthbansal/Desktop/claude code/linkedin-mcp/config.json",
"LINKEDIN_MCP_STATE_DIR": "/Users/parthbansal/Desktop/claude code/linkedin-mcp/.linkedin-mcp",
"LINKEDIN_MCP_LOG_LEVEL": "info"
}
}Codex CLIはJSONではなくTOMLを使用しますが、マッピングは一対一です:command = "node"、args = ["/Users/parthbansal/Desktop/claude code/linkedin-mcp/dist/server.js"]、そして [env] テーブル。
安全な実験
args に "--dry-run" を追加すると、アカウントに触れることができない完全に機能するサーバーを登録できます:
"args": [
"/Users/parthbansal/Desktop/claude code/linkedin-mcp/dist/server.js",
"--dry-run"
]ドライランモードでは、リクエストがlinkedin.comに到達することはなく、投稿、招待、メッセージ、申請が送信されることもありません。これは、エージェントに初めてツールの表面を探索させる正しい方法です。
サーバーが受け付ける他のフラグ:--headless、--config <path>、--log-level <debug|info|warn|error>、および -h / --help(stdoutがプロトコルを運ぶため、stderrに出力します)。不明なフラグはハードエラーです — タイプミスの --dry-runn によって、実際にはドライランモードでないのにドライランモードだと誤認させてはなりません。全体を通しての優先順位はコマンドラインフラグ > 環境変数 > config.json > デフォルトです。
すべての環境変数は .env.example に文書化されています。すべてオプションであり、どれも認証情報を保持しません。
開発
出力なしで型チェック:
npm run typecheckユニットテストを実行:
npm test保存時に再コンパイル:
npm run dev--dry-run
npm run dry-run は、ビルドされたサーバーを --dry-run で起動します。このモードでは、ブラウザはlinkedin.comではなく fixtures/ 内のローカルHTMLフィクスチャ を指し、すべての書き込みフローの最終送信クリックがスキップされるため、確認されたアクションはコードパス全体(検証、割り当てチェック、ダイアログ操作)を進み、何も実行せずに停止します。実行された結果には dryRun: true が含まれ、プレビューはドライランが有効であることを警告します。linkedin_login は使用できず、linkedin_session_status は常に有効を報告します。
フィクスチャは、プロフィールページ(3つのバリエーション — 直接Connectボタンがある2次のプロフィール、「More」メニューの背後にConnectがある2次のプロフィール、動作するメッセージ作成ボックスがある1次のつながり)、フィード、求人検索、Easy Applyと外部の応募者追跡システムの両方の求人詳細ページ、メッセージング、招待、つながりをカバーしています。ここで開発してください。 このサーバーでの日々の作業で実際のアカウントに触れる理由はありません。
URLがどのフィクスチャに解決されるかは、src/fixtures.ts 内の部分文字列ルールの順序付きリストによって決定されます。この順序は構造上重要です — /mynetwork/invite-connect/connections/ は /mynetwork/invit を含み、/in/tomas-eriksen は /in/ を含むため — 特定のルールは一般的なルールの上に配置され、tests/fixtures.test.ts がその順序を固定しています。
LinkedInなしでの検証
npm run verify:dryこれはコンパイルされたサーバーを --dry-run で起動し、実際のMCPクライアントがするようにstdio上でJSON-RPCを送受信し、23のケースにわたってすべての11ツールを実行します — すべての読み取りツールを対応するフィクスチャに対して、すべての書き込みツールを完全なプレビュー → 確認のハンドシェイクを通して、そして重要な拒否(古い previewToken、長すぎる投稿、2次のプロフィールへのメッセージ、外部の求人、ドライラン中の linkedin_login)を実行します。エンベロープの契約も検証します:プレビューは executed: false を報告しなければならず、確認は executed: true を報告しなければならず、stdoutはJSON-RPCのみを運ばなければなりません。
サーバー自身の起動行が dryRun: true を確認しない限り、実行を拒否するため、誤ってアカウントに作用することはありません。動作するChromiumが必要です — session_status 以外はすべてブラウザページを開きます — そして、いずれかの失敗で非ゼロの終了コードで終了し、失敗を セレクタ/ロジック の失敗(サーバーが間違っている)と ハーネス の失敗(スイープが間違っている)に分類します。
テスト
テストスイートはVitest(tests/**/*.test.ts)によって実行され、現在 レートリミッター(src/rateLimiter.ts)、設定ローダー(src/config.ts)、フィクスチャルーティング(src/fixtures.ts) をカバーしています — 3つのファイルで75ケース。3つすべては構造上隔離されています:各ケースは新しい mkdtemp ディレクトリに対して実行され、環境は process.env から読み取られるのではなく明示的に渡され、レートリミッターのクロック、スリープ、ランダム性は RateLimiterDeps を通じて注入されます。ネットワーク呼び出しを行わず、ブラウザも起動しません。
ブラウザが必要なものはすべて上記のドライランスイープにあり、ユニットスイートにはありません — そのため npm test は1秒未満で完了し、node_modules 以外に何もインストールする必要がありません。
編集前に知っておくべき規約
stdoutに書き込んではいけません。 stdoutはJSON-RPCチャネルです。1バイトの余分な出力がフレーミングを非同期化し、クライアントが接続を切断します。すべての診断情報は
Loggerを通じてstderrに出力されます。プロジェクトは
moduleResolution: "NodeNext"のESMであるため、相対インポートはTypeScriptソースでも.jsで終わる必要があります。src/types.tsとsrc/errors.tsは共有の契約です。src/selectors.tsは文字列と純粋関数のみです。
トラブルシューティング
「起動したのに何も起こらない」 — それは成功です
npm start を手動で実行すると、stderrに1行表示され、その後は見かけ上沈黙します:
{"ts":"...","level":"info","msg":"linkedin-mcp ready on stdio","version":"0.1.0","tools":11,"dryRun":false,"headless":false}それは正常なサーバーであり、ハングではありません。 MCP stdioサーバーは、ポートを持つデーモンでも、結果を出力して終了するCLIでもありません。stdin からJSON-RPCリクエストを読み取り、stdout にレスポンスを書き込むため、自己宣言後はクライアントが何かを言うのを待ってブロックします。クライアントが接続されていない場合、言うべきことは何もなく、正しいサーバーはstdoutに何も出力せずに静かにしています — そこに1バイトの余分な出力があると、プロトコルのフレーミングが非同期化されます。
つまり:npm start はこれの使い方ではありません。サーバーをMCPクライアントに登録し(下記)、クライアントに起動させます。待機中に応答することを確認したい場合は、リクエストをstdinに貼り付けてReturnキーを押します — tools/list の応答がすぐに返ってくるはずです:
printf '%s\n' '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | node dist/server.js --dry-run手動で起動したサーバーを停止するには Ctrl-C を押します。SIGINT/SIGTERM でシャットダウンし、shutting down をログに記録します。
関連する2つの症状:
クライアントに0個のツールが表示される、または「サーバーの起動に失敗しました」。 ほとんどの場合、
argsのパスが間違っているか、dist/がビルドされていません。dist/server.jsへの絶対パスを使用し、npm run buildを実行し、クライアント自身のMCPログを確認してください — サーバーのstderrはそこに出力され、config_invalidまたはNodeのモジュール解決エラーがそこにあります。準備完了の行が表示されるが、すべてのツールが失敗する。 その行が何と言っているか確認してください。
dryRun:trueはフィクスチャのみを意味し、何をしてもLinkedInに到達しません。すべての呼び出しでnot_authenticatedが返る場合は、保存されたセッションがまだないことを意味するので、linkedin_loginを実行してください。
エラーコード
失敗は、安定した code を持つMCPツールエラーとして返されます。最もよく見られるもの:
verification_required — LinkedInがCAPTCHA、チェックポイント、または認証壁を表示しました。サーバーは意図的にここで停止し、それを解決しようとは決してしません。通常のブラウザでlinkedin.comを開き、ご自身でチャレンジをクリアしてから、もう一度 linkedin_login を実行してください。これが頻繁に発生する場合は、毎日のキャップを下げるべき信号として扱ってください。
session_expired — 保存されたセッションがもはや認証されないか、LinkedInがフィードをサインインページにリダイレクトしました。linkedin_login を実行して、もう一度手動でサインインしてください。linkedin_session_status が具体的な reason を表示します。
selector_not_found — サーバーが必要な要素を見つけられませんでした。これはほとんど常に、あなたが何かを間違えたのではなく、LinkedInがマークアップを変更したことを意味します。プロジェクト内のすべの DOM セレクターは src/selectors.ts にあります。そこが唯一のメンテナンスポイントです。該当する候補リストを見つけ、その先頭に新しいセレクターを追加して再ビルドしてください。候補は順序付きリストのため、新しいセレクターを追加しても既存のものは壊れません。--log-level debug で実行すると、どのルックアップの探索が失敗したかが分かります。
rate_limited — 毎日のキャップに達しました。エラーと quota ブロックが、どのキャップに達し、それがいつリセットされるか(次回のローカル時での深夜0時)を教えてくれます。リセットを待つか、config.json でそのキャップを挙げてください。ただし、キャップの引き上は、アカウントの制限を引く起こす正にその明の行動なので、意図して行ってください。
external_application — 求人ページは応募幣を、LinkedIn の Easy Apply フォームではなく外部の応募者追跡システムに委ねます。サーバーはサードパーティ・サイトへの入力はしません。ブラウザで求人を開き、その場で応募してください。
**not_apply…。 Wait, careful. Let me redo.
not_connected — 1次接続ではない相手にメッセージを送ろとのしました。まずつながりリクエストを送り、承されるのを待ってからメッセージしてください。サーバーはこの ACanMail で回避することはありません。
他に遭遇する可能のあるコードは次の通りです: not_ауthenticated( ディスイス上にセッションがない — linkedin_login を実行)、not_easy_apply、invalid_input、confirmation_mismatch(プレビューと確認の間で引数が変更された — もう一度プレビューする)、navigation_failed、browser_error、dry_run_unsupported、config_invalid(不正な config.json。サーバー起動前に報告される)、file_not_found。
このツールがやらないこ
InMail は使いません。 メッセージは1次接続と既存の会話のみです。
外部 ATS への応募もしません。 Easy Applyのみ。LinkedIn の外に出る操作はすべて拒否されます。
CAPTCHA は解析しません。 2FA の自動機、チェックポイントの回避、その類一切をしません。
マルチアカウントには対応しません。 保存したセッションは1つ、アカウントは1つ、キーボードの前にいるのは1人だけです。
リモートメディアのアップロードはしません。 サーバーが URL を取得して投稿に添付することはありません。
セキュリティとプラバシー
保存されるものと、その場所。 すべてはこのマシン上の状態ディレクトリ以下に保存されます。既定は <cwd>/.linkedin-mcp/ で、LINKEDIN_MCP_STATE_DIR(またはLINKEDIN_MCP_STORAGE_STATE、LINKEDIN_MCP_USER_DATA_DIR、LINKEDIN_MCP_SCREENSHOT_DIR、LINKEDIN_MCP_COUNTERS でパスごとに上書きできます。
パス | 内容 |
| あなたの LinkedInCookie とオリジンストレージ。モード |
| 永続的な Chromium プロファイルディレクトリ |
| 今日のローカル日付と4つのアクションカウント |
| 診断用スクリーンショット。ローカルにのみ書き込まれる |
何も外部に送信されません。 テレメトリも、アナリティクスも、クラッシュリポートも、外部への接続も一切ありません。唯一のネットワーク接続先は linkedin.com で、あなた自身のブラウザセッションを通じてのみ行われます。--dry-run ではそれすら行われません。
スクリーンショットはローカル専用です。 自身がデバッグするために sports デのスクリーンショットディレクトリ to write; それらはアップロードも、ツールの出力に含まれることもありません。
ログは意図的に最小限です。 診断情報は stderr に出力されます。クッキー、storageState の内容、レジュメファイルの内容がログやシリアライズにされることは一切ありません。ツールの失敗時には、実行後のログではなくエラーコードだけが記録されるため、メッセージ本文やレジュメのパスがクライアントによってキャプチャされた stderr に漏れることはありません。redactConfig は、起動時にサーバーがログする有効設定行から絶対パス(とホームディレクトリ)を取り除きます。
gitignoreの保証。 .gitignore は、.env と .env.*(.env.example と残る)、.linkedin-mcp/ 状態ディレクトリ全体、任意の深さの storageState.json、chromium-profile/、counters.json、screenshots/、*.log、さらに node_modules/、dist/、coverage/ を無視します。追跡されるのは config.example.json とあなたの config.json のみで、その中にはキャップとタイムアウトしかありません。
storageState.json をコミットしないでください。 これは生の認証情報です。状態ディレクトリを機密として扱ってください。 storageState.json を読める人は、パスワードや2FAコードなしであなたの LinkedIn アカウントとして普通の操作ができてしまいます。漏洩した可を性があれば、LinkedIn のセキュリティ設定からすべてのセッションをログアウトし、そのファイルを削除し、もう一度ログインしてください。
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseBqualityBmaintenanceEnables full control over LinkedIn profiles through browser automation, allowing reading, editing, adding, removing entries, and publishing posts directly from conversations.41294MIT
- AlicenseNot gradedqualityDmaintenanceEnables fetching detailed LinkedIn profile data by automating a browser session with your LinkedIn cookie to access full profiles.214MIT
- AlicenseBqualityCmaintenanceEnables read-only extraction of LinkedIn profile data via MCP tools, using a local browser bridge for secure, authenticated access without exposing browser credentials.2MIT
- AlicenseAqualityBmaintenanceLets an AI assistant operate LinkedIn through an authenticated browser session, enabling profile management, posting, networking, messaging, job search, and automated applications.1003831MIT
Related MCP Connectors
Give AI agents the LinkedIn tools to find, qualify, engage, and follow up with prospects.
Browser MCP for logged-in tasks. Uses your Chrome — credentials stay local. Zero-token replay.
Let AI tools securely access your LinkedIn network and DMs
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/bansalsahab/linkdin-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server