linkedin-cli-tool 0.2.0
LinkedIn CLI tool using Safari session cookies
Requires Python: >=3.10

# LinkedIn CLI

A command-line interface for LinkedIn, powered by Safari session cookies and LinkedIn's internal Voyager API.

Browse your feed, view notifications, create posts, react to content, search people, and view profiles — all from the terminal.

## Installation

```bash
pip install linkedin-cli-tool
```

Or install from source:

```bash
git clone https://github.com/utsmannn/licli.git
cd licli
pip install -e .
```

## Requirements

- macOS with Safari
- Python 3.10+
- Active LinkedIn session in Safari (you must be logged in)

## Commands

### Authentication

```bash
# Test connection and see your profile
li auth
```

### Profile

```bash
# View your own profile
li me

# View someone else's profile
li profile johndoe
```

### Feed

```bash
# Show your LinkedIn feed
li feed

# Limit number of posts
li feed -n 5
```

### Notifications

```bash
# View recent notifications
li notif

# Limit to 5 notifications
li notif -n 5
```

Shows notification headlines, timestamps, read/unread status, and content previews. Activity-linked notifications include a copyable `li view` command.

### View Post Detail

```bash
# By activity URN
li view urn:li:activity:7426564508296400897

# By numeric ID only
li view 7426564508296400897

# From a feed URL path
li view /feed/update/urn:li:activity:7426564508296400897
```

Displays full post text, author, reaction breakdown (like, celebrate, love, etc.), comment/share counts, and inline comments.

### Create a Post

```bash
# Simple post
li post "Hello LinkedIn!"

# With visibility setting
li post "Hello connections!" --visibility CONNECTIONS

# With mention (by URN)
li post "Great work @John!" --mention "John:urn:li:fsd_profile:ACoAAabc123"

# With mention (by profile ID — auto-resolves URN)
li post "Great work @John!" --mention "John:johndoe"
```

### React to a Post

```bash
# Like a post (default)
li react urn:li:activity:7426564508296400897

# Choose reaction type
li react 7426564508296400897 --type celebrate
li react 7426564508296400897 --type love
li react 7426564508296400897 --type insightful
li react 7426564508296400897 --type funny
li react 7426564508296400897 --type curious

# Remove your reaction
li react 7426564508296400897 --undo
```

### Comment on a Post

```bash
# Top-level comment on a post
li comment urn:li:activity:7426564508296400897 "Great post!"

# By numeric ID
li comment 7426564508296400897 "Nice one!"

# Reply to a specific comment (URN from `li view` output)
li comment "urn:li:comment:(activity:7426564508296400897,7426673256407007233)" "Thanks!"
```

### Search People

```bash
li search "software engineer"
li search "John Doe" -n 5
```

### Search Posts

```bash
# Search for posts by keyword
li search "artificial intelligence" --type posts

# Limit results
li search "machine learning" --type posts -n 5
```

## How It Works

This CLI extracts session cookies from Safari's cookie store (`~/Library/Cookies/Cookies.binarycookies`) to authenticate with LinkedIn's internal APIs:

- **Voyager REST API** — used for read operations (feed, profile, search, notifications, post detail) and comments
- **GraphQL API** — used for creating posts and fetching comment threads
- **RSC (React Server Components) API** — used for reactions (like/unlike)

No OAuth flow or API keys required — just log into LinkedIn in Safari and you're ready to go.

### Cookies Used

| Cookie | Purpose |
|--------|---------|
| `li_at` | LinkedIn authentication token |
| `JSESSIONID` | CSRF token |

## Project Structure

```
linkedin_cli/
  __init__.py        # Package metadata
  auth.py            # Safari cookie extraction
  client.py          # LinkedIn API client (Voyager + RSC)
  cli.py             # Click CLI commands
  utils.py           # Formatting helpers
  rsc_template.json  # RSC payload template for reactions
```

## Disclaimer

This tool uses LinkedIn's unofficial internal API. Use responsibly:

- LinkedIn may rate limit or restrict your account
- The API may change without notice
- This is for personal use only