LinkedIn MCP Server
README.md
# LinkedIn MCP Server
Lets Claude Code post to **your own** LinkedIn: write, preview, save drafts, schedule, comment and react, all by talking to Claude. Nothing is published until you type a confirmation keyword.
## What you need
- Claude Code
- Node.js 20 or newer (`node -v` to check)
- macOS or Linux (Windows is untested)
- A LinkedIn account
- About 10 minutes
## Setup
### 1. Create your own LinkedIn app (5 minutes)
LinkedIn only lets software post for you through an "app" that you own. It is free and nobody else sees it.
1. Go to [linkedin.com/developers/apps](https://www.linkedin.com/developers/apps) and click **Create app**.
2. Fill in:
- **App name**: anything, e.g. "My Claude MCP"
- **LinkedIn Page**: any company page you admin. If you have none, create a blank one first; LinkedIn insists on it.
- **App logo**: any image
3. Open the **Products** tab and request both:
- **Share on LinkedIn**
- **Sign In with LinkedIn using OpenID Connect**
4. Open the **Auth** tab and add this redirect URL exactly:
`http://localhost:8585/callback`
5. Still on the **Auth** tab, copy your **Client ID** and **Client Secret**. Keep the secret private; it is a password.
### 2. Install
The easy way: open Claude Code and paste this, with your two values filled in.
> Clone https://github.com/ayushnagvanshi101098-ship-it/linkedin-mcp-server.git into ~/linkedin-mcp-server, run `npm install` and `npm run build` in it, then add it to Claude Code as a user-scope MCP server named `linkedin` that runs `node ~/linkedin-mcp-server/dist/index.js` with the env vars LINKEDIN_CLIENT_ID=your_client_id and LINKEDIN_CLIENT_SECRET=your_client_secret.
Or by hand in a terminal:
```bash
git clone https://github.com/ayushnagvanshi101098-ship-it/linkedin-mcp-server.git ~/linkedin-mcp-server
cd ~/linkedin-mcp-server
npm install
npm run build
claude mcp add linkedin --scope user \
-e LINKEDIN_CLIENT_ID=your_client_id \
-e LINKEDIN_CLIENT_SECRET=your_client_secret \
-- node ~/linkedin-mcp-server/dist/index.js
```
### 3. Connect your LinkedIn
Quit and reopen Claude Code, then say:
> authenticate with linkedin
A browser tab opens. Approve it and you are connected. To check at any time, ask "what's my linkedin status".
LinkedIn logins expire after roughly two months. When posting stops working, say "authenticate with linkedin" again.
### 4. Post
> Post this to LinkedIn: [your text]
Claude shows a preview of how it will look in the feed. Nothing goes out until you type **POST IT**.
## Things you can say
- "Post this to LinkedIn: ..." (text, or with an image, or a PDF document/carousel)
- "Preview this post" / "Lint this post"
- "Save this as a draft" / "Show my drafts" / "Publish draft 3"
- "Schedule draft 3 for tomorrow at 9am"
- "Show my post history"
- "Delete that post"
## The safety keywords
Every action that changes something waits for you to type a keyword.
| You are about to | Type |
|---|---|
| Publish a post or a draft | `POST IT` |
| Delete a published post | `DELETE IT` |
| Send a DM or a connection request | `SEND IT` |
| Save or delete a draft, schedule, react, comment | `CONFIRM` |
## Good to know
- **The post checker is opinionated.** It blocks em dashes, a few cliché phrases ("game-changer", "move the needle") and anything over 3,000 characters. If you want to post anyway, say `OVERRIDE LINT`. The rules live in `src/lint/rules.ts`.
- **Video posts do not work yet.** Text, image and PDF posts do. Upload videos on LinkedIn directly for now.
- **Scheduled posts need the scheduler, and it is macOS only.** Say "install the linkedin scheduler" once. Your Mac must be awake at the scheduled time.
- **Commenting and reacting on other people's posts** needs LinkedIn's Community Management API, which most personal apps do not have. On your own posts it works.
## Optional: reading LinkedIn (inbox, profiles, search)
These tools read things the official API cannot, by driving a real browser logged in as you. You do not need them to post.
```bash
cd ~/linkedin-mcp-server && npx playwright install chromium # about 280 MB, once
```
Then say "linkedin scrape login" and log in by hand in the window that opens.
LinkedIn's terms discourage automated browsing. Calls are slowed down and run one at a time, but this part is at your own risk. The posting tools above use the official API and are unaffected.
## Where your data lives
All on your machine, nothing is sent anywhere except LinkedIn.
| File | What it is |
|---|---|
| `~/.linkedin-mcp-tokens.json` | Your LinkedIn login token |
| `~/.linkedin-mcp/data.db` | Drafts, schedule, post history |
| `~/.linkedin-mcp/config.json` | Settings |
| `~/.linkedin-mcp/scrape-session.json` | Browser login for the optional reading tools |
**Never share these files or your Client Secret.** Anyone holding them can act as you on LinkedIn.
## All tools
| Tool | What it does | Needs |
|---|---|---|
| `linkedin_auth` | Connect your LinkedIn account | |
| `linkedin_status` | Connection, token expiry, database health | |
| `linkedin_lint` | Check a post against the rules | |
| `linkedin_preview` | Show the post as the feed will, with the "see more" fold | |
| `linkedin_post` | Publish a post | `POST IT` |
| `linkedin_drafts_save` | Save or update a draft | `CONFIRM` |
| `linkedin_drafts_list` / `linkedin_drafts_get` | Browse drafts | |
| `linkedin_drafts_publish` | Publish a saved draft | `POST IT` |
| `linkedin_drafts_delete` | Delete a draft | `CONFIRM` |
| `linkedin_schedule_add` / `linkedin_schedule_remove` | Schedule or cancel a draft | `CONFIRM` |
| `linkedin_schedule_list` | List scheduled posts | |
| `linkedin_scheduler_install` / `_status` / `_uninstall` | The background job that fires scheduled posts (macOS) | |
| `linkedin_posts_history` | Posts published through this server | |
| `linkedin_perf_poll` | Record a post's impressions and reactions by hand | `CONFIRM` |
| `linkedin_post_engagement` | Likes, comments, shares for a post (Community Management API) | |
| `linkedin_delete` | Delete a published post | `DELETE IT` |
| `linkedin_react` / `linkedin_comment` | React to or comment on a post | `CONFIRM` |
| `linkedin_confirm` | Carries your keyword to the waiting action | |
| `linkedin_scrape_login` / `linkedin_scrape_status` | Browser login for the reading tools | |
| `linkedin_inbox` / `linkedin_conversation_get` / `linkedin_conversation_search` | Read your DMs | |
| `linkedin_message_send` / `linkedin_connect_send` | Send a DM or connection request | `SEND IT` |
| `linkedin_profile_get` / `linkedin_profile_sidebar` / `linkedin_people_search` | Read profiles, search people | |
| `linkedin_company_get` / `linkedin_company_posts` | Read company pages | |
## Settings
Set these next to the Client ID and Secret if you need them. Most people need none.
| Variable | What it does |
|---|---|
| `LINKEDIN_MCP_HOME` | Where the browser session and diagnostics go (default `~/.linkedin-mcp`) |
| `LINKEDIN_MCP_MEMORY_DIR` | A folder holding an optional `post_log.md`, `running_theses.md` and `narrative_arcs.md`. If the files are missing, those features are skipped. |
| `LINKEDIN_SCRAPE_HEADLESS` | Set to `false` to watch the reading tools' browser window instead of running it hidden |
## Troubleshooting
- **"Port 8585 is already in use"** during login: something else is on that port. Close it and try again.
- **Login page says the redirect does not match**: the redirect URL in step 1.4 must be exactly `http://localhost:8585/callback`.
- **Claude does not see the tools**: quit and reopen Claude Code, then run `claude mcp list` and check `linkedin` is connected.
- **Something failed mid-action**: a report is written to `~/.linkedin-mcp/diagnostics/`.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues