@mhdd_24/linkedin-mcp
# @mhdd_24/linkedin-mcp
MCP server that posts to **LinkedIn** through the **LinkedIn API**. Use it from Cursor, Claude Desktop, VS Code Copilot, or any MCP-compatible client.
You type natural language — the assistant calls `create_post` for you. No manual member ID setup; your **LinkedIn OAuth access token** resolves identity automatically.
**Full documentation:** [docs/WIKI.md](docs/WIKI.md)
---
## How it works (30 seconds)
```
You (chat) → MCP client → linkedin-mcp → LinkedIn userinfo (access token)
→ LinkedIn ugcPosts API
→ Text post on your profile
```
1. **Access token** calls `userinfo` → returns `memberId`, `name`, `email`
2. **Author URN** is built from `memberId` — not hardcoded
3. **Visibilities** come from config — validated before posting
4. **`create_post`** validates visibility, POSTs the share, returns the post URN
---
## Prerequisites
| Requirement | Notes |
|-------------|-------|
| **Node.js 18+** | Uses native fetch |
| **LinkedIn OAuth access token** | Member token with required scopes (see below) |
| **Default visibility** (optional) | `DEFAULT_VISIBILITY` so you don't pass it every time |
### Required OAuth scopes
| Scope | Purpose |
|-------|---------|
| `openid` | OpenID Connect identity |
| `profile` | Display name |
| `email` | Email address |
| `w_member_social` | Create posts on your profile |
Obtain a token via the [LinkedIn OAuth 2.0 Authorization Code flow](https://learn.microsoft.com/en-us/linkedin/shared/authentication/authorization-code-flow).
---
## Install
### Option A — npm (recommended after publish)
```bash
npm install -g @mhdd_24/linkedin-mcp
```
This installs the `linkedin-mcp` CLI and compiles `dist/` via the package `prepack` script.
### Option B — npx (no global install)
```bash
npx @mhdd_24/linkedin-mcp
```
Downloads and runs the latest published version on each invocation.
### Option C — clone and build (contributors)
```bash
git clone https://github.com/Mhdd-24/Linkedin-MCP.git
cd Linkedin-MCP
npm install
npm run build
node dist/index.js
```
---
## Configure your MCP client
### Cursor
Edit **Cursor Settings → MCP** or `~/.cursor/mcp.json`:
```json
{
"mcpServers": {
"linkedin": {
"command": "npx",
"args": ["-y", "@mhdd_24/linkedin-mcp"],
"env": {
"LINKEDIN_ACCESS_TOKEN": "<your-oauth-access-token>",
"DEFAULT_VISIBILITY": "PUBLIC"
}
}
}
}
```
**After global install**, you can use:
```json
"command": "linkedin-mcp"
```
**Local development:**
```json
"command": "node",
"args": ["/path/to/linkedin-mcp/dist/index.js"]
```
Restart Cursor (or toggle the MCP server off/on) after saving.
### Claude Desktop
`%APPDATA%\Claude\claude_desktop_config.json` (Windows) or `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS):
```json
{
"mcpServers": {
"linkedin": {
"command": "npx",
"args": ["-y", "@mhdd_24/linkedin-mcp"],
"env": {
"LINKEDIN_ACCESS_TOKEN": "<your-oauth-access-token>",
"DEFAULT_VISIBILITY": "PUBLIC"
}
}
}
}
```
---
## Environment variables
| Variable | Required | Default | Purpose |
|----------|----------|---------|---------|
| `LINKEDIN_ACCESS_TOKEN` | Yes\* | — | OAuth access token for userinfo + posting |
| `DEFAULT_VISIBILITY` | No | `PUBLIC` | Default audience for `create_post` |
| `LINKEDIN_API_BASE_URL` | No | `https://api.linkedin.com` | LinkedIn API host |
\* Or pass `accessToken` on each tool call.
**Aliases:** `LI_ACCESS_TOKEN`, `accessToken`, `defaultVisibility`, etc. (see [WIKI](docs/WIKI.md)).
**Never commit** access tokens. Put them only in MCP `env` or a local `.env` (for `npm run dev`).
---
## Tools
| Tool | Purpose |
|------|---------|
| `whoami` | Test token — shows memberId, name, email, author URN |
| `list_visibilities` | Lists valid post visibility values |
| `create_post` | Create a text post on your LinkedIn profile |
---
## Usage
### Step 1 — Verify setup (optional)
In chat:
> Run **whoami** on the linkedin MCP.
Expected: your LinkedIn identity and author URN.
### Step 2 — See valid visibilities (optional)
> **list_visibilities**
Examples: `PUBLIC`, `CONNECTIONS`
### Step 3 — Create a post
> Post to LinkedIn: _Just shipped a new feature! Excited to share what we've been building._
> Create a LinkedIn post with visibility PUBLIC: _Happy to announce our open-source MCP server for LinkedIn integration._
### `create_post` parameters
| Parameter | Required | Example |
|-----------|----------|---------|
| `text` | Yes | "Just shipped a new feature!" |
| `visibility` | No\* | "PUBLIC" |
| `accessToken` | No | Only if not in env |
\* Optional when `DEFAULT_VISIBILITY` is set in MCP config.
---
## What happens after `npm install`?
1. Package files land in `node_modules/@mhdd_24/linkedin-mcp/` (or global prefix if `-g`).
2. `prepack` / publish includes compiled **`dist/`** — no local build needed for end users.
3. The **`linkedin-mcp`** bin points to `dist/index.js`.
4. Your MCP client runs that entry over **stdio** (stdin/stdout = MCP protocol; logs go to stderr).
5. On startup: `validateEnv()` warns if access token is missing.
6. Tools are registered; the server waits for `CallTool` requests from the AI.
---
## After publishing to npm (maintainers)
1. **Bump version** in `package.json` and `src/config/linkedin.config.ts` (`LI.SERVER.VERSION`).
2. **Build and test:** `npm run build` then test with local `mcp.json`.
3. **Publish:** `npm publish --access public` (logged in as package owner).
4. **Users update** by restarting MCP — `npx` picks up the new version automatically.
5. **Global install users:** `npm update -g @mhdd_24/linkedin-mcp`.
Current package version: **1.0.0**.
See [WIKI — Publishing](docs/WIKI.md#17-publishing-and-post-release) for the full checklist.
---
## Troubleshooting
| Problem | Fix |
|---------|-----|
| MCP server won't start | Check Node.js 18+ is installed |
| No access token provided | Set `LINKEDIN_ACCESS_TOKEN` or pass `accessToken` on the tool |
| Invalid visibility | Run `list_visibilities`; use an exact match (case-insensitive) |
| visibility is required | Set `DEFAULT_VISIBILITY` in env or pass visibility on `create_post` |
| userinfo failed: 401 | Token expired or invalid — refresh your OAuth token |
| Post failed: 403 | Token missing `w_member_social` scope |
More detail: [docs/WIKI.md § Troubleshooting](docs/WIKI.md#16-troubleshooting).
---
## License
ISC
TDQS
Scored across 3 tools
Each tool serves a distinct purpose: whoami resolves user identity, list_visibilities provides valid visibility options, and create_post handles posting. No overlap in functionality.
All tool names follow a consistent verb_noun snake_case pattern: create_post, list_visibilities, whoami (verb-only). The pattern is uniform and predictable.
3 tools is minimal but appropriate for a focused LinkedIn posting server. It covers the core workflow: identify user, check options, create post. Could be expanded slightly, but not under-scoped.
The tool surface covers the essential steps for creating a text post: user info, visibility choices, and posting. Missing update/delete or media posting, but for a basic text share it is complete.