io.github.alexey-pelykh/linkedctl
CLI and MCP server for the LinkedIn API
★ 0AGPL-3.0devtools
Install
Config snippet generator goes here (5 client tabs)
README

[](https://github.com/alexey-pelykh/linkedctl/actions/workflows/ci.yml)
[](https://github.com/alexey-pelykh/linkedctl/actions/workflows/codeql.yml)
[](https://www.gnu.org/licenses/agpl-3.0.txt)
OAuth2 CLI and MCP server for the [LinkedIn](https://www.linkedin.com) API.
## What It Does
- **Post content** — text, images, video, documents, articles, multi-image carousels, and polls
- **Comments & reactions** — create, list, and delete comments and reactions on posts
- **Organization support** — post, comment, react, and view analytics as an organization
- **Analytics** — per-post, per-member, and per-organization statistics
- **Media uploads** — upload images, video, and documents to LinkedIn
- **Draft posts** — save posts as drafts before publishing
- **OAuth 2.0 authentication** with your own LinkedIn app
- **Direct token passing** for tokens obtained from other applications
- **MCP server** for AI assistant integration (Claude, Cursor, etc.)
- **CLI** for scriptable LinkedIn operations
## Prerequisites
- [Node.js](https://nodejs.org) >= 24
- A [LinkedIn Developer App](https://www.linkedin.com/developers/apps) with appropriate permissions
## Installation
```sh
npm install -g linkedctl
```
Or run directly:
```sh
npx linkedctl --help
```
## Quick Start
1. Create a LinkedIn app at [linkedin.com/developers](https://www.linkedin.com/developers/apps)
2. Configure OAuth 2.0 credentials
3. Authenticate:
```sh
linkedctl auth login --client-id YOUR_CLIENT_ID --client-secret YOUR_CLIENT_SECRET
```
4. Start using:
```sh
linkedctl post "Hello from LinkedCtl!"
```
See the [OAuth Setup Guide](https://github.com/alexey-pelykh/linkedctl/blob/main/docs/oauth-setup.md) for detailed step-by-step instructions.
## MCP Integration
### MCP Client Configuration
<details>
<summary><b>Claude Desktop</b></summary>
Add to your Claude Desktop configuration (`claude_desktop_config.json`):
```json
{
"mcpServers": {
"linkedctl": {
"command": "npx",
"args": ["linkedctl", "mcp"]
}
}
}
```
</details>
<details>
<summary><b>Claude Code</b></summary>
```sh
claude mcp add linkedctl -- npx linkedctl mcp
```
</details>
<details>
<summary><b>Cursor</b></summary>
Add to `.cursor/mcp.json` in your project root:
```json
{
"mcpServers": {
"linkedctl": {
"command": "npx",
"args": ["linkedctl", "mcp"]
}
}
}
```
</details>
<details>
<summary><b>Windsurf</b></summary>
Add to `~/.codeium/windsurf/mcp_config.json`:
```json
{
"mcpServers": {
"linkedctl": {
"command": "npx",
"args": ["linkedctl", "mcp"]
}
}
}
```
</details>
### Available Tools
All tools accept an optional `profile` parameter to select a configuration profile.
#### Authentication
| Tool | Description |
| ------------- | --------------------------------------------------------------- |
| `whoami` | Show the current user's name, email, and profile picture URL |
| `auth_status` | Show authentication status for a profile |
| `auth_revoke` | Revoke the access token server-side and clear local credentials |
#### Posts
| Tool | Description |
| ------------- | -------------------------------------------------------------------------- |
| `post_create` | Create a post on LinkedIn with optional media, poll, or article attachment |
| `post_get` | Fetch a single post by URN |
| `post_list` | List posts with pagination (supports `as_org` for organization posts) |
| `post_update` | Update the commentary text of an existing post |
| `post_delete` | Delete a post by URN |
`post_create` supports rich content types:
| Parameter | Description |
| ---------------------------- | ----------------------------------------------------- |
| `text` | Post text content (required) |
| `visibility` | `PUBLIC` or `CONNECTIONS` (default `PUBLIC`) |
| `draft` | Save as draft instead of publishing |
| `image` / `image_file` | Attach a single image (URN or local file path) |
| `video` / `video_file` | Attach a video (URN or local file path) |
| `document