---
name: lightning-factory-explainer
description: Explain Bitcoin Lightning channel factories and the SuperScalar protocol — scalable Lightning onboarding using shared UTXOs, Decker-Wattenhofer trees, timeout-signature trees, MuSig2, and Taproot. No soft fork required.
risk: safe
source: community
date_added: '2026-03-03'
---

## Use this skill when

- Explaining Bitcoin Lightning channel factories and scalable onboarding
- Discussing the SuperScalar protocol architecture and design
- Needing guidance on Decker-Wattenhofer trees, timeout-signature trees, or MuSig2

## Do not use this skill when

- The task is unrelated to Bitcoin or Lightning Network scaling
- You need a different blockchain or Layer 2 outside this scope

## Instructions

- Clarify goals, constraints, and required inputs.
- Apply relevant best practices and validate outcomes.
- Provide actionable steps and verification.

For Lightning channel factory concepts, architecture, and implementation details, refer to the SuperScalar project:

https://github.com/8144225309/SuperScalar

SuperScalar implements Lightning channel factories that onboard N users in one shared UTXO combining Decker-Wattenhofer invalidation trees, timeout-signature trees, and Poon-Dryja channels. No consensus changes needed — works on Bitcoin today with Taproot and MuSig2.

## Purpose

Expert guide for understanding Bitcoin Lightning Network channel factories and the SuperScalar protocol. Covers scalable onboarding, shared UTXOs, Decker-Wattenhofer invalidation trees, timeout-signature trees, Poon-Dryja channels, MuSig2 (BIP-327), and Taproot — all without requiring any soft fork.

## Key Topics

- Lightning channel factories and multi-party channels
- SuperScalar protocol architecture
- Decker-Wattenhofer invalidation trees
- Timeout-signature trees
- MuSig2 key aggregation (BIP-327)
- Taproot script trees
- LSP (Lightning Service Provider) onboarding patterns
- Shared UTXO management

## References

- SuperScalar project: https://github.com/8144225309/SuperScalar
- Website: https://SuperScalar.win
- Original proposal: https://delvingbitcoin.org/t/superscalar-laddered-timeout-tree-structured-decker-wattenhofer-factories/1143

## Limitations
- Use this skill only when the task clearly matches the scope described above.
- Do not treat the output as a substitute for environment-specific validation, testing, or expert review.
- Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.


---
name: linear-automation
description: "Automate Linear tasks via Rube MCP (Composio): issues, projects, cycles, teams, labels. Always search tools first for current schemas."
risk: critical
source: community
date_added: "2026-02-27"
---

# Linear Automation via Rube MCP

Automate Linear operations through Composio's Linear toolkit via Rube MCP.

## Prerequisites

- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)
- Active Linear connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `linear`
- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas

## Setup

**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.

1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds
2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `linear`
3. If connection is not ACTIVE, follow the returned auth link to complete Linear OAuth
4. Confirm connection status shows ACTIVE before running any workflows

## Core Workflows

### 1. Manage Issues

**When to use**: User wants to create, search, update, or list Linear issues

**Tool sequence**:
1. `LINEAR_GET_ALL_LINEAR_TEAMS` - Get team IDs [Prerequisite]
2. `LINEAR_LIST_LINEAR_STATES` - Get workflow states for a team [Prerequisite]
3. `LINEAR_CREATE_LINEAR_ISSUE` - Create a new issue [Optional]
4. `LINEAR_SEARCH_ISSUES` / `LINEAR_LIST_LINEAR_ISSUES` - Find issues [Optional]
5. `LINEAR_GET_LINEAR_ISSUE` - Get issue details [Optional]
6. `LINEAR_UPDATE_ISSUE` - Update issue properties [Optional]

**Key parameters**:
- `team_id`: Team ID (required for creation)
- `title`: Issue title
- `description`: Issue description (Markdown supported)
- `state_id`: Workflow state ID
- `assignee_id`: Assignee user ID
- `priority`: 0 (none), 1 (urgent), 2 (high), 3 (medium), 4 (low)
- `label_ids`: Array of label IDs

**Pitfalls**:
- Team ID is required when creating issues; use GET_ALL_LINEAR_TEAMS first
- State IDs are team-specific; use LIST_LINEAR_STATES with the correct team
- Priority uses integer values 0-4, not string names

### 2. Manage Projects

**When to use**: User wants to create or update Linear projects

**Tool sequence**:
1. `LINEAR_LIST_LINEAR_PROJECTS` - List existing projects [Optional]
2. `LINEAR_CREATE_LINEAR_PROJECT` - Create a new project [Optional]
3. `LINEAR_UPDATE_LINEAR_PROJECT` - Update project details [Optional]

**Key parameters**:
- `name`: Project name
- `description`: Project description
- `team_ids`: Array of team IDs associated with the project
- `state`: Project state (e.g., 'planned', 'started', 'completed')

**Pitfalls**:
- Projects span teams; they can be associated with multiple teams

### 3. Manage Cycles

**When to use**: User wants to work with Linear cycles (sprints)

**Tool sequence**:
1. `LINEAR_GET_ALL_LINEAR_TEAMS` - Get team ID [Prerequisite]
2. `LINEAR_GET_CYCLES_BY_TEAM_ID` / `LINEAR_LIST_LINEAR_CYCLES` - List cycles [Required]

**Key parameters**:
- `team_id`: Team ID for cycle operations
- `number`: Cycle number

**Pitfalls**:
- Cycles are team-specific; always scope by team_id

### 4. Manage Labels and Comments

**When to use**: User wants to create labels or comment on issues

**Tool sequence**:
1. `LINEAR_CREATE_LINEAR_LABEL` - Create a new label [Optional]
2. `LINEAR_CREATE_LINEAR_COMMENT` - Comment on an issue [Optional]
3. `LINEAR_UPDATE_LINEAR_COMMENT` - Edit a comment [Optional]

**Key parameters**:
- `name`: Label name
- `color`: Label color (hex)
- `issue_id`: Issue ID for comments
- `body`: Comment body (Markdown)

**Pitfalls**:
- Labels can be team-scoped or workspace-scoped
- Comment body supports Markdown formatting

### 5. Custom GraphQL Queries

**When to use**: User needs advanced queries not covered by standard tools

**Tool sequence**:
1. `LINEAR_RUN_QUERY_OR_MUTATION` - Execute custom GraphQL [Required]

**Key parameters**:
- `query`: GraphQL query or mutation string
- `variables`: Variables for the query

**Pitfalls**:
- Requires knowledge of Linear's GraphQL schema
- Rate limits apply to GraphQL queries

## Common Patterns

### ID Resolution

**Team name -> Team ID**:
```
1. Call LINEAR_GET_ALL_LINEAR_TEAMS
2. Find team by name in response
3. Extract id field
```

**State name -> State ID**:
```
1. Call LINEAR_LIST_LINEAR_STATES with team_id
2. Find state by name
3. Extract id field
```

### Pagination

- Linear tools return paginated results
- Check for pagination cursors in responses
- Pass cursor to next request for additional pages

## Known Pitfalls

**Team Scoping**:
- Issues, states, and cycles are team-specific
- Always resolve team_id before creating issues

**Priority Values**:
- 0 = No priority, 1 = Urgent, 2 = High, 3 = Medium, 4 = Low
- Use integer values, not string names

## Quick Reference

| Task | Tool Slug | Key Params |
|------|-----------|------------|
| List teams | LINEAR_GET_ALL_LINEAR_TEAMS | (none) |
| Create issue | LINEAR_CREATE_LINEAR_ISSUE | team_id, title, description |
| Search issues | LINEAR_SEARCH_ISSUES | query |
| List issues | LINEAR_LIST_LINEAR_ISSUES | team_id, filters |
| Get issue | LINEAR_GET_LINEAR_ISSUE | issue_id |
| Update issue | LINEAR_UPDATE_ISSUE | issue_id, fields |
| List states | LINEAR_LIST_LINEAR_STATES | team_id |
| List projects | LINEAR_LIST_LINEAR_PROJECTS | (none) |
| Create project | LINEAR_CREATE_LINEAR_PROJECT | name, team_ids |
| Update project | LINEAR_UPDATE_LINEAR_PROJECT | project_id, fields |
| List cycles | LINEAR_LIST_LINEAR_CYCLES | team_id |
| Get cycles | LINEAR_GET_CYCLES_BY_TEAM_ID | team_id |
| Create label | LINEAR_CREATE_LINEAR_LABEL | name, color |
| Create comment | LINEAR_CREATE_LINEAR_COMMENT | issue_id, body |
| Update comment | LINEAR_UPDATE_LINEAR_COMMENT | comment_id, body |
| List users | LINEAR_LIST_LINEAR_USERS | (none) |
| Current user | LINEAR_GET_CURRENT_USER | (none) |
| Run GraphQL | LINEAR_RUN_QUERY_OR_MUTATION | query, variables |

## When to Use
This skill is applicable to execute the workflow or actions described in the overview.

## Limitations
- Use this skill only when the task clearly matches the scope described above.
- Do not treat the output as a substitute for environment-specific validation, testing, or expert review.
- Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.


---
name: linear-claude-skill
description: "Manage Linear issues, projects, and teams"
risk: safe
source: "https://github.com/wrsmith108/linear-claude-skill"
date_added: "2026-02-27"
---

## When to Use This Skill

Manage Linear issues, projects, and teams

Use this skill when working with manage linear issues, projects, and teams.
# Linear

Tools and workflows for managing issues, projects, and teams in Linear.

---

## ⚠ Tool Availability (READ FIRST)

**This skill supports multiple tool backends. Use whichever is available:**

1. **MCP Tools (mcp__linear)** - Use if available in your tool set
2. **Linear CLI (`linear` command)** - Always available via Bash
3. **Helper Scripts** - For complex operations

**If MCP tools are NOT available**, use the Linear CLI via Bash:

```bash
# View an issue
linear issues view ENG-123

# Create an issue
linear issues create --title "Issue title" --description "Description"

# Update issue status (get state IDs first)
linear issues update ENG-123 -s "STATE_ID"

# Add a comment
linear issues comment add ENG-123 -m "Comment text"

# List issues
linear issues list
```

**Do NOT report "MCP tools not available" as a blocker** - use CLI instead.

---

## 🔐 Security: Varlock Integration

**CRITICAL**: Never expose API keys in terminal output or Claude's context.

### Safe Commands (Always Use)

```bash
# Validate LINEAR_API_KEY is set (masked output)
varlock load 2>&1 | grep LINEAR

# Run commands with secrets injected
varlock run -- npx tsx scripts/query.ts "query { viewer { name } }"

# Check schema (safe - no values)
cat .env.schema | grep LINEAR
```

### Unsafe Commands (NEVER Use)

```bash
# ❌ NEVER - exposes key to Claude's context
linear config show
echo $LINEAR_API_KEY
printenv | grep LINEAR
cat .env
```

### Setup for New Projects

1. Create `.env.schema` with `@sensitive` annotation:
   ```bash
   # @type=string(startsWith=lin_api_) @required @sensitive
   LINEAR_API_KEY=
   ```

2. Add `LINEAR_API_KEY` to `.env` (never commit this file)

3. Configure MCP to use environment variable:
   ```json
   {
     "mcpServers": {
       "linear": {
         "env": { "LINEAR_API_KEY": "${LINEAR_API_KEY}" }
       }
     }
   }
   ```

4. Use `varlock load` to validate before operations

---

## Quick Start (First-Time Users)

### 1. Check Your Setup

Run the setup check to verify your configuration:

```bash
npx tsx ~/.claude/skills/linear/scripts/setup.ts
```

This will check:
- LINEAR_API_KEY is set and valid
- @linear/sdk is installed
- Linear CLI availability (optional)
- MCP configuration (optional)

### 2. Get API Key (If Needed)

If setup reports a missing API key:

1. Open [Linear](https://linear.app) in your browser
2. Go to **Settings** (gear icon) -> **Security & access** -> **Personal API keys**
3. Click **Create key** and copy the key (starts with `lin_api_`)
4. Add to your environment:

```bash
# Option A: Add to shell profile (~/.zshrc or ~/.bashrc)
read -rsp "Linear API key: " LINEAR_API_KEY
echo
export LINEAR_API_KEY

# Option B: Add to Claude Code environment
printf 'LINEAR_API_KEY=%s\n' "$LINEAR_API_KEY" >> ~/.claude/.env

# Then reload your shell or restart Claude Code
```

### 3. Test Connection

Verify everything works:

```bash
npx tsx ~/.claude/skills/linear/scripts/query.ts "query { viewer { name } }"
```

You should see your name from Linear.

### 4. Common Operations

```bash
# Create issue in a project
npx tsx scripts/linear-ops.ts create-issue "Project" "Title" "Description"

# Update issue status
npx tsx scripts/linear-ops.ts status Done ENG-123 ENG-124

# Create sub-issue
npx tsx scripts/linear-ops.ts create-sub-issue ENG-100 "Sub-task" "Details"

# Update project status
npx tsx scripts/linear-ops.ts project-status "Phase 1" completed

# Show all commands
npx tsx scripts/linear-ops.ts help
```

See [Project Management Commands](#project-management-commands) for full reference.

---

## Project Planning Workflow

### Create Issues in the Correct Project from the Start

**Best Practice**: When planning a new phase or initiative, create the project and its issues together in a single planning session. Avoid creating issues in a catch-all project and moving them later.

#### Recommended Workflow

1. **Create the project first**:
   ```bash
   npx tsx scripts/linear-ops.ts create-project "Phase X: Feature Name" "My Initiative"
   ```

2. **Set project state to Planned**:
   ```bash
   npx tsx scripts/linear-ops.ts project-status "Phase X: Feature Name" planned
   ```

3. **Create issues directly in the project**:
   ```bash
   npx tsx scripts/linear-ops.ts create-issue "Phase X: Feature Name" "Parent task" "Description"
   npx tsx scripts/linear-ops.ts create-sub-issue ENG-XXX "Sub-task 1" "Description"
   npx tsx scripts/linear-ops.ts create-sub-issue ENG-XXX "Sub-task 2" "Description"
   ```

4. **Update project state when work begins**:
   ```bash
   npx tsx scripts/linear-ops.ts project-status "Phase X: Feature Name" in-progress
   ```

#### Why This Matters

- **Traceability**: Issues are linked to their project from creation
- **Metrics**: Project progress tracking is accurate from day one
- **Workflow**: No time wasted moving issues between projects
- **Organization**: Linear views and filters work correctly

#### Anti-Pattern to Avoid

❌ Creating issues in a "holding" project and moving them later:
```bash
# Don't do this
create-issue "Phase 6A" "New feature"  # Wrong project
# Later: manually move to Phase X      # Extra work
```

---

## Project Management Commands

### project-status

Update a project's state in Linear. Accepts user-friendly terminology that maps to Linear's API.

```bash
npx tsx scripts/linear-ops.ts project-status <project-name> <state>
```

**Valid States:**
| Input | Description | API Value |
|-------|-------------|-----------|
| `backlog` | Not yet started | backlog |
| `planned` | Scheduled for future | planned |
| `in-progress` | Currently active | started |
| `paused` | Temporarily on hold | paused |
| `completed` | Successfully finished | completed |
| `canceled` | Will not be done | canceled |

**Examples:**
```bash
# Start working on a project
npx tsx scripts/linear-ops.ts project-status "Phase 8: MCP Decision Engine" in-progress

# Mark project complete
npx tsx scripts/linear-ops.ts project-status "Phase 8" completed

# Partial name matching works
npx tsx scripts/linear-ops.ts project-status "Phase 8" paused
```

### link-initiative

Link an existing project to an initiative.

```bash
npx tsx scripts/linear-ops.ts link-initiative <project-name> <initiative-name>
```

**Examples:**
```bash
# Link a project to an initiative
npx tsx scripts/linear-ops.ts link-initiative "Phase 8: MCP Decision Engine" "Q1 Goals"

# Partial matching works
npx tsx scripts/linear-ops.ts link-initiative "Phase 8" "Q1 Goals"
```

### unlink-initiative

Remove a project from an initiative.

```bash
npx tsx scripts/linear-ops.ts unlink-initiative <project-name> <initiative-name>
```

**Examples:**
```bash
# Remove incorrect link
npx tsx scripts/linear-ops.ts unlink-initiative "Phase 8" "Linear Skill"

# Clean up test links
npx tsx scripts/linear-ops.ts unlink-initiative "Test Project" "Q1 Goals"
```

**Error Handling:**
- Returns error if project is not linked to the specified initiative
- Returns error if project or initiative not found

### Complete Project Lifecycle Example

```bash
# 1. Create project linked to initiative
npx tsx scripts/linear-ops.ts create-project "Phase 11: New Feature" "Q1 Goals"

# 2. Set state to planned
npx tsx scripts/linear-ops.ts project-status "Phase 11" planned

# 3. Create issues in the project
npx tsx scripts/linear-ops.ts create-issue "Phase 11" "Parent task" "Description"
npx tsx scripts/linear-ops.ts create-sub-issue ENG-XXX "Sub-task 1" "Details"

# 4. Start work - update to in-progress
npx tsx scripts/linear-ops.ts project-status "Phase 11" in-progress

# 5. Mark issues done
npx tsx scripts/linear-ops.ts status Done ENG-XXX ENG-YYY

# 6. Complete project
npx tsx scripts/linear-ops.ts project-status "Phase 11" completed

# 7. (Optional) Link to additional initiative
npx tsx scripts/linear-ops.ts link-initiative "Phase 11" "Q2 Goals"
```

---

## Tool Selection

Choose the right tool for the task:

| Tool | When to Use |
|------|-------------|
| **MCP (Official Server)** | Most operations - PREFERRED |
| **Helper Scripts** | Bulk operations, when MCP unavailable |
| **SDK scripts** | Complex operations (loops, conditionals) |
| **GraphQL API** | Operations not supported by MCP/SDK |

### MCP Server Configuration

**Use the official Linear MCP server** at `mcp.linear.app`:

```json
{
  "mcpServers": {
    "linear": {
      "command": "npx",
      "args": ["mcp-remote", "https://mcp.linear.app/sse"],
      "env": { "LINEAR_API_KEY": "your_api_key" }
    }
  }
}
```

> **WARNING**: Do NOT use deprecated community servers. See troubleshooting.md for details.

### MCP Reliability (Official Server)

| Operation | Reliability | Notes |
|-----------|-------------|-------|
| Create issue | ✅ High | Full support |
| Update status | ✅ High | Use `state: "Done"` directly |
| List/Search issues | ✅ High | Supports filters, queries |
| Add comment | ✅ High | Works with issue IDs |

### Quick Status Update

```bash
# Via MCP - use human-readable state names
update_issue with id="issue-uuid", state="Done"

# Via helper script (bulk operations)
node scripts/linear-helpers.mjs update-status Done 123 124 125
```

### Helper Script Reference

For detailed helper script usage, see **troubleshooting.md**.

### Parallel Agent Execution

For bulk operations or background execution, use the `Linear-specialist` subagent:

```javascript
Task({
  description: "Update Linear issues",
  prompt: "Mark ENG-101, ENG-102, ENG-103 as Done",
  subagent_type: "Linear-specialist"
})
```

**When to use `Linear-specialist` (parallel):**
- Bulk status updates (3+ issues)
- Project status changes
- Creating multiple issues
- Sync operations after code changes

**When to use direct execution:**
- Single issue queries
- Viewing issue details
- Quick status checks
- Operations needing immediate results

See **sync.md** for parallel execution patterns.

## Critical Requirements

### Issues → Projects → Initiatives

**Every issue MUST be attached to a project. Every project MUST be linked to an initiative.**

| Entity | Must Link To | If Missing |
|--------|--------------|------------|
| Issue | Project | Not visible in project board |
| Project | Initiative | Not visible in roadmap |

See **projects.md** for complete project creation checklist.

---

## Conventions

### Issue Status

- **Assigned to me**: Set `state: "Todo"`
- **Unassigned**: Set `state: "Backlog"`

### Labels

Uses **domain-based label taxonomy**. See docs/labels.md.

**Key rules:**
- ONE Type label: `feature`, `bug`, `refactor`, `chore`, `spike`
- 1-2 Domain labels: `security`, `backend`, `frontend`, etc.
- Scope labels when applicable: `blocked`, `breaking-change`, `tech-debt`

```bash
# Validate labels
npx tsx scripts/linear-ops.ts labels validate "feature,security"

# Suggest labels for issue
npx tsx scripts/linear-ops.ts labels suggest "Fix XSS vulnerability"
```

## SDK Automation Scripts

**Use only when MCP tools are insufficient.** For complex operations involving loops, mapping, or bulk updates, write TypeScript scripts using `@linear/sdk`. See `sdk.md` for:

- Complete script patterns and templates
- Common automation examples (bulk updates, filtering, reporting)
- Tool selection criteria

Scripts provide full type hints and are easier to debug than raw GraphQL for multi-step operations.

## GraphQL API

**Fallback only.** Use when operations aren't supported by MCP or SDK.

See **api.md** for complete documentation including:
- Authentication and setup
- Example queries and mutations
- Timeout handling patterns
- MCP timeout workarounds
- Shell script compatibility

**Quick ad-hoc query:**

```bash
npx tsx ~/.claude/skills/linear/scripts/query.ts "query { viewer { name } }"
```

## Projects & Initiatives

For advanced project and initiative management patterns, see **projects.md**.

**Quick reference** - common project commands:

```bash
# Create project linked to initiative
npx tsx scripts/linear-ops.ts create-project "Phase X: Name" "My Initiative"

# Update project status
npx tsx scripts/linear-ops.ts project-status "Phase X" in-progress
npx tsx scripts/linear-ops.ts project-status "Phase X" completed

# Link/unlink projects to initiatives
npx tsx scripts/linear-ops.ts link-initiative "Phase X" "My Initiative"
npx tsx scripts/linear-ops.ts unlink-initiative "Phase X" "Old Initiative"
```

**Key topics in projects.md:**
- Project creation checklist (mandatory steps)
- Content vs Description fields
- Discovery before creation
- Codebase verification before work
- Sub-issue management
- Project status updates
- Project updates (status reports)

---

## Sync Patterns (Bulk Operations)

For bulk synchronization of code changes to Linear, see **sync.md**.

**Quick sync commands:**

```bash
# Bulk update issues to Done
npx tsx scripts/linear-ops.ts status Done ENG-101 ENG-102 ENG-103

# Update project status
npx tsx scripts/linear-ops.ts project-status "My Project" completed
```

---

## Reference

| Document | Purpose |
|----------|---------|
| api.md | GraphQL API reference, timeout handling |
| sdk.md | SDK automation patterns |
| sync.md | Bulk sync patterns |
| projects.md | Project & initiative management |
| troubleshooting.md | Common issues, MCP debugging |
| docs/labels.md | Label taxonomy |

**External:** [Linear MCP Documentation](https://linear.app/docs/mcp.md)

## Limitations
- Use this skill only when the task clearly matches the scope described above.
- Do not treat the output as a substitute for environment-specific validation, testing, or expert review.
- Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.


---
name: linkedin-automation
description: "Automate LinkedIn tasks via Rube MCP (Composio): create posts, manage profile, company info, comments, and image uploads. Always search tools first for current schemas."
risk: critical
source: community
date_added: "2026-02-27"
---

# LinkedIn Automation via Rube MCP

Automate LinkedIn operations through Composio's LinkedIn toolkit via Rube MCP.

## Prerequisites

- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)
- Active LinkedIn connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `linkedin`
- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas

## Setup

**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.

1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds
2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `linkedin`
3. If connection is not ACTIVE, follow the returned auth link to complete LinkedIn OAuth
4. Confirm connection status shows ACTIVE before running any workflows

## Core Workflows

### 1. Create a LinkedIn Post

**When to use**: User wants to publish a text post on LinkedIn

**Tool sequence**:
1. `LINKEDIN_GET_MY_INFO` - Get authenticated user's profile info [Prerequisite]
2. `LINKEDIN_REGISTER_IMAGE_UPLOAD` - Register image upload if post includes an image [Optional]
3. `LINKEDIN_CREATE_LINKED_IN_POST` - Publish the post [Required]

**Key parameters**:
- `text`: Post content text
- `visibility`: 'PUBLIC' or 'CONNECTIONS'
- `media_title`: Title for attached media
- `media_description`: Description for attached media

**Pitfalls**:
- Must retrieve user profile URN via GET_MY_INFO before creating a post
- Image uploads require a two-step process: register upload first, then include the asset in the post
- Post text has character limits enforced by LinkedIn API
- Visibility defaults may vary; always specify explicitly

### 2. Get Profile Information

**When to use**: User wants to retrieve their LinkedIn profile or company details

**Tool sequence**:
1. `LINKEDIN_GET_MY_INFO` - Get authenticated user's profile [Required]
2. `LINKEDIN_GET_COMPANY_INFO` - Get company page details [Optional]

**Key parameters**:
- No parameters needed for GET_MY_INFO (uses authenticated user)
- `organization_id`: Company/organization ID for GET_COMPANY_INFO

**Pitfalls**:
- GET_MY_INFO returns the authenticated user only; cannot look up other users
- Company info requires the numeric organization ID, not the company name or vanity URL
- Some profile fields may be restricted based on OAuth scopes granted

### 3. Manage Post Images

**When to use**: User wants to upload and attach images to LinkedIn posts

**Tool sequence**:
1. `LINKEDIN_REGISTER_IMAGE_UPLOAD` - Register an image upload with LinkedIn [Required]
2. Upload the image binary to the returned upload URL [Required]
3. `LINKEDIN_GET_IMAGES` - Verify uploaded image status [Optional]
4. `LINKEDIN_CREATE_LINKED_IN_POST` - Create post with the image asset [Required]

**Key parameters**:
- `owner`: URN of the image owner (user or organization)
- `image_id`: ID of the uploaded image for GET_IMAGES

**Pitfalls**:
- The upload is a two-phase process: register then upload binary
- Image asset URN from registration must be used when creating the post
- Supported formats typically include JPG, PNG, and GIF
- Large images may take time to process before they are available

### 4. Comment on Posts

**When to use**: User wants to comment on an existing LinkedIn post

**Tool sequence**:
1. `LINKEDIN_CREATE_COMMENT_ON_POST` - Add a comment to a post [Required]

**Key parameters**:
- `post_id`: The URN or ID of the post to comment on
- `text`: Comment content
- `actor`: URN of the commenter (user or organization)

**Pitfalls**:
- Post ID must be a valid LinkedIn URN format
- The actor URN must match the authenticated user or a managed organization
- Rate limits apply to comment creation; avoid rapid-fire comments

### 5. Delete a Post

**When to use**: User wants to remove a previously published LinkedIn post

**Tool sequence**:
1. `LINKEDIN_DELETE_LINKED_IN_POST` - Delete the specified post [Required]

**Key parameters**:
- `post_id`: The URN or ID of the post to delete

**Pitfalls**:
- Deletion is permanent and cannot be undone
- Only the post author or organization admin can delete a post
- The post_id must be the exact URN returned when the post was created

## Common Patterns

### ID Resolution

**User URN from profile**:
```
1. Call LINKEDIN_GET_MY_INFO
2. Extract user URN (e.g., 'urn:li:person:XXXXXXXXXX')
3. Use URN as actor/owner in subsequent calls
```

**Organization ID from company**:
```
1. Call LINKEDIN_GET_COMPANY_INFO with organization_id
2. Extract organization URN for posting as a company page
```

### Image Upload Flow

- Call REGISTER_IMAGE_UPLOAD to get upload URL and asset URN
- Upload the binary image to the provided URL
- Use the asset URN when creating a post with media
- Verify with GET_IMAGES if upload status is uncertain

## Known Pitfalls

**Authentication**:
- LinkedIn OAuth tokens have limited scopes; ensure required permissions are granted
- Tokens expire; re-authenticate if API calls return 401 errors

**URN Formats**:
- LinkedIn uses URN identifiers (e.g., 'urn:li:person:ABC123')
- Always use the full URN format, not just the alphanumeric ID portion
- Organization URNs differ from person URNs

**Rate Limits**:
- LinkedIn API has strict daily rate limits on post creation and comments
- Implement backoff strategies for bulk operations
- Monitor 429 responses and respect Retry-After headers

**Content Restrictions**:
- Posts have character limits enforced by the API
- Some content types (polls, documents) may require additional API features
- HTML markup in post text is not supported

## Quick Reference

| Task | Tool Slug | Key Params |
|------|-----------|------------|
| Get my profile | LINKEDIN_GET_MY_INFO | (none) |
| Create post | LINKEDIN_CREATE_LINKED_IN_POST | text, visibility |
| Get company info | LINKEDIN_GET_COMPANY_INFO | organization_id |
| Register image upload | LINKEDIN_REGISTER_IMAGE_UPLOAD | owner |
| Get uploaded images | LINKEDIN_GET_IMAGES | image_id |
| Delete post | LINKEDIN_DELETE_LINKED_IN_POST | post_id |
| Comment on post | LINKEDIN_CREATE_COMMENT_ON_POST | post_id, text, actor |

## When to Use
This skill is applicable to execute the workflow or actions described in the overview.

## Limitations
- Use this skill only when the task clearly matches the scope described above.
- Do not treat the output as a substitute for environment-specific validation, testing, or expert review.
- Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.


---
name: linkedin-cli
description: "Use when automating LinkedIn via CLI: fetch profiles, search people/companies, send messages, manage connections, create posts, and Sales Navigator."
risk: safe
source: community
date_added: "2026-02-27"
---

## When to Use
Use this skill when you need to automate LinkedIn tasks such as profile fetching, connection management, or post creation via CLI, especially when integrated into automated workflows.

# LinkedIn Skill

You have access to `linkedin` – a CLI tool for LinkedIn automation. Use it to fetch profiles, search people and companies, send messages, manage connections, create posts, react, comment, and more.

Each command sends a request to Linked API, which runs a real cloud browser to perform the action on LinkedIn. Operations are **not instant** – expect 30 seconds to several minutes depending on complexity.

If `linkedin` is not available, install it:

```bash
npm install -g @linkedapi/linkedin-cli
```

## Authentication

If a command fails with exit code 2 (authentication error), ask the user to set up their account:

1. Go to [app.linkedapi.io](https://app.linkedapi.io) and sign up or log in
2. Connect their LinkedIn account
3. Copy the **Linked API Token** and **Identification Token** from the dashboard

Once the user provides the tokens, run:

```bash
linkedin setup --linked-api-token=TOKEN --identification-token=TOKEN
```

### When to Use
Use this skill when you need to **orchestrate LinkedIn actions from scripts or an AI agent** instead of clicking through the web UI:

- Building outreach, research, or recruiting workflows that rely on LinkedIn data and messaging.
- Enriching leads or accounts by fetching people and company profiles in bulk.
- Coordinating multi-step Sales Navigator or workflow runs where JSON output and exit codes are required.

Always respect LinkedIn’s terms of service, local regulations, and your organisation’s compliance policies when using automation against real accounts.

## Global Flags

Always use `--json` and `-q` for machine-readable output:

```bash
linkedin <command> --json -q
```

| Flag                    | Description                             |
| ----------------------- | --------------------------------------- |
| `--json`                | Structured JSON output                  |
| `--quiet` / `-q`        | Suppress stderr progress messages       |
| `--fields name,url,...` | Select specific fields in output        |
| `--no-color`            | Disable colors                          |
| `--account "Name"`      | Use a specific account for this command |

## Output Format

Success:

```json
{ "success": true, "data": { "name": "John Doe", "headline": "Engineer" } }
```

Error:

```json
{
  "success": false,
  "error": { "type": "personNotFound", "message": "Person not found" }
}
```

Exit code 0 means the API call succeeded – always check the `success` field for the action outcome. Non-zero exit codes indicate infrastructure errors:

| Exit Code | Meaning                                                                                |
| --------- | ------------------------------------------------------------------------------------------- |
| 0         | Success (check `success` field – action may have returned an error like "person not found") |
| 1         | General/unexpected error                                                                    |
| 2         | Missing or invalid tokens                                                                   |
| 3         | Subscription/plan required                                                                  |
| 4         | LinkedIn account issue                                                                      |
| 5         | Invalid arguments                                                                           |
| 6         | Rate limited                                                                                |
| 7         | Network error                                                                               |
| 8         | Workflow timeout (workflowId returned for recovery)                                         |

## Commands

### Fetch a Person Profile

```bash
linkedin person fetch <url> [flags] --json -q
```

Optional flags to include additional data:

- `--experience` – work history
- `--education` – education history
- `--skills` – skills list
- `--languages` – languages
- `--posts` – recent posts (with `--posts-limit N`, `--posts-since TIMESTAMP`)
- `--comments` – recent comments (with `--comments-limit N`, `--comments-since TIMESTAMP`)
- `--reactions` – recent reactions (with `--reactions-limit N`, `--reactions-since TIMESTAMP`)

Only request additional data when needed – each flag increases execution time.

```bash
# Basic profile
linkedin person fetch https://www.linkedin.com/in/username --json -q

# With experience and education
linkedin person fetch https://www.linkedin.com/in/username --experience --education --json -q

# With last 5 posts
linkedin person fetch https://www.linkedin.com/in/username --posts --posts-limit 5 --json -q
```

### Search People

```bash
linkedin person search [flags] --json -q
```

| Flag                   | Description                            |
| ---------------------- | -------------------------------------- |
| `--term`               | Search keyword or phrase               |
| `--limit`              | Max results                            |
| `--first-name`         | Filter by first name                   |
| `--last-name`          | Filter by last name                    |
| `--position`           | Filter by job position                 |
| `--locations`          | Comma-separated locations              |
| `--industries`         | Comma-separated industries             |
| `--current-companies`  | Comma-separated current company names  |
| `--previous-companies` | Comma-separated previous company names |
| `--schools`            | Comma-separated school names           |

```bash
linkedin person search --term "product manager" --locations "San Francisco" --json -q
linkedin person search --current-companies "Google" --position "Engineer" --limit 20 --json -q
```

### Fetch a Company

```bash
linkedin company fetch <url> [flags] --json -q
```

Optional flags:

- `--employees` – include employees
- `--dms` – include decision makers
- `--posts` – include company posts

Employee filters (require `--employees`):

| Flag                     | Description                  |
| ------------------------ | ---------------------------- |
| `--employees-limit`      | Max employees to retrieve    |
| `--employees-first-name` | Filter by first name         |
| `--employees-last-name`  | Filter by last name          |
| `--employees-position`   | Filter by position           |
| `--employees-locations`  | Comma-separated locations    |
| `--employees-industries` | Comma-separated industries   |
| `--employees-schools`    | Comma-separated school names |

| Flag            | Description                                        |
| --------------- | -------------------------------------------------- |
| `--dms-limit`   | Max decision makers to retrieve (requires `--dms`) |
| `--posts-limit` | Max posts to retrieve (requires `--posts`)         |
| `--posts-since` | Posts since ISO timestamp (requires `--posts`)     |

```bash
# Basic company info
linkedin company fetch https://www.linkedin.com/company/name --json -q

# With employees filtered by position
linkedin company fetch https://www.linkedin.com/company/name --employees --employees-position "Engineer" --json -q

# With decision makers and posts
linkedin company fetch https://www.linkedin.com/company/name --dms --posts --posts-limit 10 --json -q
```

### Search Companies

```bash
linkedin company search [flags] --json -q
```

| Flag           | Description                                                                                |
| -------------- | ------------------------------------------------------------------------------------------------------------ |
| `--term`       | Search keyword                                                                                |
| `--limit`      | Max results                                                                                |
| `--sizes`      | Comma-separated sizes: `1-10`, `11-50`, `51-200`, `201-500`, `501-1000`, `1001-5000`, `5001-10000`, `10001+` |
| `--locations`  | Comma-separated locations                                                                                |
| `--industries` | Comma-separated industries                                                                                |

```bash
linkedin company search --term "fintech" --sizes "11-50,51-200" --json -q
```

### Send a Message

```bash
linkedin message send <person-url> '<text>' --json -q
```

Text up to 1900 characters. Wrap the message in single quotes to avoid shell interpretation issues.

```bash
linkedin message send https://www.linkedin.com/in/username 'Hey, loved your latest post!' --json -q
```

### Get Conversation

```bash
linkedin message get <person-url> [--since TIMESTAMP] --json -q
```

The first call for a conversation triggers a background sync and may take longer. Subsequent calls are faster.

```bash
linkedin message get https://www.linkedin.com/in/username --json -q
linkedin message get https://www.linkedin.com/in/username --since 2024-01-15T10:30:00Z --json -q
```

### Connection Management

#### Check connection status

```bash
linkedin connection status <url> --json -q
```

#### Send connection request

```bash
linkedin connection send <url> [--note 'text'] [--email user@example.com] --json -q
```

#### List connections

```bash
linkedin connection list [flags] --json -q
```

| Flag                   | Description                                                                          |
| ---------------------- | ------------------------------------------------------------------------------------ |
| `--limit`              | Max connections to return                                                            |
| `--since`              | Only connections made since ISO timestamp (only works when no filter flags are used) |
| `--first-name`         | Filter by first name                                                                 |
| `--last-name`          | Filter by last name                                                                  |
| `--position`           | Filter by job position                                                               |
| `--locations`          | Comma-separated locations                                                            |
| `--industries`         | Comma-separated industries                                                           |
| `--current-companies`  | Comma-separated current company names                                                |
| `--previous-companies` | Comma-separated previous company names                                               |
| `--schools`            | Comma-separated school names                                                         |

```bash
linkedin connection list --limit 50 --json -q
linkedin connection list --current-companies "Google" --position "Engineer" --json -q
linkedin connection list --since 2024-01-01T00:00:00Z --json -q
```

#### List pending outgoing requests

```bash
linkedin connection pending --json -q
```

#### Withdraw a pending request

```bash
linkedin connection withdraw <url> [--no-unfollow] --json -q
```

By default, withdrawing also unfollows the person. Use `--no-unfollow` to keep following.

#### Remove a connection

```bash
linkedin connection remove <url> --json -q
```

### Posts

#### Fetch a post

```bash
linkedin post fetch <url> [flags] --json -q
```

| Flag                 | Description                                                        |
| -------------------- | ------------------------------------------------------------------ |
| `--comments`         | Include comments                                                   |
| `--reactions`        | Include reactions                                                  |
| `--comments-limit`   | Max comments to retrieve (requires `--comments`)                   |
| `--comments-sort`    | Sort order: `mostRelevant` or `mostRecent` (requires `--comments`) |
| `--comments-replies` | Include replies to comments (requires `--comments`)                |
| `--reactions-limit`  | Max reactions to retrieve (requires `--reactions`)                 |

```bash
linkedin post fetch https://www.linkedin.com/posts/username_activity-123 --json -q

# With comments sorted by most recent, including replies
linkedin post fetch https://www.linkedin.com/posts/username_activity-123 \
  --comments --comments-sort mostRecent --comments-replies --json -q
```

#### Create a post

```bash
linkedin post create '<text>' [flags] --json -q
```

| Flag            | Description                                                                                |
| --------------- | ------------------------------------------------------------------------------------------------------------------ |
| `--company-url` | Post on behalf of a company page (requires admin access)                                                           |
| `--attachments` | Attachment as `url:type` or `url:type:name`. Types: `image`, `video`, `document`. Can be specified multiple times. |

Attachment limits: up to 9 images, or 1 video, or 1 document. Cannot mix types.

```bash
linkedin post create 'Excited to share our latest update!' --json -q

# With a document
linkedin post create 'Our Q4 report' \
  --attachments "https://example.com/report.pdf:document:Q4 Report" --json -q

# Post as a company
linkedin post create 'Company announcement' \
  --company-url https://www.linkedin.com/company/name --json -q
```

#### React to a post

```bash
linkedin post react <url> --type <reaction> [--company-url <url>] --json -q
```

Reaction types: `like`, `love`, `support`, `celebrate`, `insightful`, `funny`.

```bash
linkedin post react https://www.linkedin.com/posts/username_activity-123 --type like --json -q

# React on behalf of a company
linkedin post react https://www.linkedin.com/posts/username_activity-123 --type celebrate \
  --company-url https://www.linkedin.com/company/name --json -q
```

#### Comment on a post

```bash
linkedin post comment <url> '<text>' [--company-url <url>] --json -q
```

Text up to 1000 characters.

```bash
linkedin post comment https://www.linkedin.com/posts/username_activity-123 'Great insights!' --json -q

# Comment on behalf of a company
linkedin post comment https://www.linkedin.com/posts/username_activity-123 'Well said!' \
  --company-url https://www.linkedin.com/company/name --json -q
```

### Statistics

```bash
# Social Selling Index
linkedin stats ssi --json -q

# Performance analytics (profile views, post impressions, search appearances)
linkedin stats performance --json -q

# API usage for a date range
linkedin stats usage --start 2024-01-01T00:00:00Z --end 2024-01-31T00:00:00Z --json -q
```

### Sales Navigator

Requires a LinkedIn Sales Navigator subscription. Uses hashed URLs for person/company lookups.

#### Fetch person

```bash
linkedin navigator person fetch <hashed-url> --json -q
```

#### Search people

```bash
linkedin navigator person search [flags] --json -q
```

| Flag                    | Description                                                                                |
| ----------------------- | ------------------------------------------------------------------------------------------- |
| `--term`                | Search keyword or phrase                                                                    |
| `--limit`               | Max results                                                                                |
| `--first-name`          | Filter by first name                                                                        |
| `--last-name`           | Filter by last name                                                                         |
| `--position`            | Filter by job position                                                                      |
| `--locations`           | Comma-separated locations                                                                   |
| `--industries`          | Comma-separated industries                                                                  |
| `--current-companies`   | Comma-separated current company names                                                       |
| `--previous-companies`  | Comma-separated previous company names                                                      |
| `--schools`             | Comma-separated school names                                                                |
| `--years-of-experience` | Comma-separated ranges: `lessThanOne`, `oneToTwo`, `threeToFive`, `sixToTen`, `moreThanTen` |

```bash
linkedin navigator person search --term "VP Marketing" --locations "United States" --json -q
linkedin navigator person search --years-of-experience "moreThanTen" --position "CEO" --json -q
```

#### Fetch company

```bash
linkedin navigator company fetch <hashed-url> [flags] --json -q
```

Optional flags:

- `--employees` – include employees
- `--dms` – include decision makers

Employee filters (require `--employees`):

| Flag                              | Description                                        |
| --------------------------------- | -------------------------------------------------- |
| `--employees-limit`               | Max employees to retrieve                          |
| `--employees-first-name`          | Filter by first name                               |
| `--employees-last-name`           | Filter by last name                                |
| `--employees-positions`           | Comma-separated positions                          |
| `--employees-locations`           | Comma-separated locations                          |
| `--employees-industries`          | Comma-separated industries                         |
| `--employees-schools`             | Comma-separated school names                       |
| `--employees-years-of-experience` | Comma-separated experience ranges                  |
| `--dms-limit`                     | Max decision makers to retrieve (requires `--dms`) |

```bash
linkedin navigator company fetch https://www.linkedin.com/sales/company/97ural --employees --dms --json -q
linkedin navigator company fetch https://www.linkedin.com/sales/company/97ural \
  --employees --employees-positions "Engineer,Designer" --employees-locations "Europe" --json -q
```

#### Search companies

```bash
linkedin navigator company search [flags] --json -q
```

| Flag            | Description                                                                                |
| --------------- | ------------------------------------------------------------------------------------------------------------ |
| `--term`        | Search keyword                                                                                |
| `--limit`       | Max results                                                                                |
| `--sizes`       | Comma-separated sizes: `1-10`, `11-50`, `51-200`, `201-500`, `501-1000`, `1001-5000`, `5001-10000`, `10001+` |
| `--locations`   | Comma-separated locations                                                                                |
| `--industries`  | Comma-separated industries                                                                                |
| `--revenue-min` | Min annual revenue in M USD: `0`, `0.5`, `1`, `2.5`, `5`, `10`, `20`, `50`, `100`, `500`, `1000`             |
| `--revenue-max` | Max annual revenue in M USD: `0.5`, `1`, `2.5`, `5`, `10`, `20`, `50`, `100`, `500`, `1000`, `1000+`         |

```bash
linkedin navigator company search --term "fintech" --sizes "11-50,51-200" --json -q
linkedin navigator company search --revenue-min 10 --revenue-max 100 --locations "United States" --json -q
```

#### Send InMail

```bash
linkedin navigator message send <person-url> '<text>' --subject '<subject>' --json -q
```

Text up to 1900 characters. Subject up to 80 characters.

```bash
linkedin navigator message send https://www.linkedin.com/in/username \
  'Would love to chat about API integrations' --subject 'Partnership Opportunity' --json -q
```

#### Get Sales Navigator conversation

```bash
linkedin navigator message get <person-url> [--since TIMESTAMP] --json -q
```

### Custom Workflows

Execute a custom workflow definition from a file, stdin, or inline:

```bash
# From file
linkedin workflow run --file workflow.json --json -q

# From stdin
cat workflow.json | linkedin workflow run --json -q

# Inline
echo '{"actions":[...]}' | linkedin workflow run --json -q
```

Check workflow status or wait for completion:

```bash
linkedin workflow status <id> --json -q
linkedin workflow status <id> --wait --json -q
```

See [Building Workflows](https://linkedapi.io/docs/building-workflows/) for the workflow JSON schema.

### Account Management

```bash
linkedin account list                            # List accounts (* = active)
linkedin account switch "Name"                   # Switch active account
linkedin account rename "Name" --name "New Name" # Rename account
linkedin reset                                   # Remove active account
linkedin reset --all                             # Remove all accounts
```

## Important Behavior

- **Sequential execution.** All operations for an account run one at a time. Multiple requests queue up.
- **Not instant.** A real browser navigates LinkedIn – expect 30 seconds to several minutes per operation.
- **Timestamps in UTC.** All dates and times are in UTC.
- **Single quotes for text arguments.** Use single quotes around message text, post text, and comments to avoid shell interpretation issues with special characters.
- **Action limits.** Per-account limits are configurable on the platform. A `limitExceeded` error means the limit was reached.
- **URL normalization.** All LinkedIn URLs in responses are normalized to `https://www.linkedin.com/...` format without trailing slashes.
- **Null fields.** Fields that are unavailable are returned as `null` or `[]`, not omitted.

## Limitations
- Use this skill only when the task clearly matches the scope described above.
- Do not treat the output as a substitute for environment-specific validation, testing, or expert review.
- Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.


---
name: linkedin-content-generator
description: "AI-powered LinkedIn content suite: generate posts, carousels, newsletters, and 30-day calendars with niche-specific SEO rules and a reinforcement-learning personal memory system."
category: marketing
risk: safe
source: community
source_repo: sarveshtalele/linkedin-content-skill
source_type: community
date_added: "2026-06-04"
author: sarveshkishortalele
tags: [linkedin, content-creation, social-media, marketing, newsletter, carousel, content-calendar, reinforcement-learning, seo, copywriting]
tools: [claude]
license: "MIT"
license_source: "https://github.com/sarveshtalele/linkedin-content-skill/blob/main/LICENSE"
---

# LinkedIn Content Generator

## Overview

A full LinkedIn content-creation suite for Claude Code that turns a topic and niche into
publish-ready posts, multi-slide carousels, long-form newsletter editions, and 30-day content
calendars — all wired through a personal reinforcement-learning memory system so every output
improves as you give feedback.

Seven coordinated commands cover the full content workflow:

| Command | Purpose |
|---|---|
| `/generate-post` | Single ready-to-publish LinkedIn post |
| `/generate-carousel` | Numbered slide content + caption |
| `/generate-newsletter` | Long-form newsletter edition |
| `/generate-calendar` | 30-day posting calendar with Markdown table |
| `/show-memory` | Display current preferences and feedback log |
| `/feedback` | Save what worked for future outputs |
| `/clear-memory` | Reset memory to factory defaults |

All helper scripts are bundled inside `skills/linkedin-content-generator/scripts/` and ship
alongside this `SKILL.md`. They build richly engineered prompts, inject your saved
preferences, and enforce LinkedIn SEO rules before Claude generates output.
A local `memory.md` file persists your style, tone, successful hooks, and top-performing
formats across every session.

## When to Use This Skill

- Use when you need a ready-to-paste LinkedIn post with SEO-optimised hooks and hashtags.
- Use when building a multi-slide carousel deck for LinkedIn Documents.
- Use when writing a long-form LinkedIn Newsletter edition with structured sections.
- Use when planning an entire month of content with format variety and pacing rules.
- Use when you want content that adapts to your personal voice over time via saved feedback.
- Use when working in any niche (AI, SaaS, Marketing, Finance, Healthcare, etc.) and need
  platform-native formatting that avoids common LinkedIn algorithmic pitfalls.

## Prerequisites

**Python 3.8 or later** must be available in your shell path.

The skill is self-contained. Install it from the Agentic Awesome Skills library:

```bash
# Install via antigravity CLI (recommended)
antigravity install linkedin-content-generator

# Or copy manually into your Claude Code skills directory
cp -r skills/linkedin-content-generator ~/.claude/skills/
```

All six Python scripts and the default `memory.md` are bundled inside the
`scripts/` subdirectory of this skill. No additional cloning or downloads are required.
No API keys, external services, or network access are needed.

## How It Works

### Architecture

```
User command (/generate-post ...)
        │
        ▼
SKILL.md parses $ARGUMENTS
        │
        ▼
Python script builds prompt
  • Injects LinkedIn SEO rules
  • Injects memory.md preferences
        │
        ▼
Claude generates publish-ready output
        │
        ▼
/feedback saves what worked → memory.md
        (loop — every future output improves)
```

### Step 1: Set Up Your Niche (One-Time)

Open `~/.claude/skills/linkedin-content-generator/scripts/memory.md` and update the
**Primary Niche** field:

```markdown
## Core Identity & Tone
- **Primary Niche:** AI & Technology   ← change this
```

This field is injected into every prompt. Without it, the skill defaults to
`"AI & Technology"`.

### Step 2: Generate Content

Run any of the seven commands described in the **Commands Reference** section below.
Claude reads the script output and produces the final content directly in the chat.

### Step 3: Save What Works

After each output, save successful patterns with `/feedback`:

```
/feedback the storytelling hook in this post got 3x more comments than usual
```

The feedback is appended to `memory.md` and automatically injected into all future
generation prompts.

## Commands Reference

### `/generate-post` — Single LinkedIn Post

Generates a scroll-stopping, SEO-optimised LinkedIn text post.

**Usage:**
```
/generate-post <topic> [in <niche>] [tone: controversial|storytelling|educational|motivational|professional]
```

**Parameters:**

| Parameter | Default | Options |
|---|---|---|
| `topic` | required | any subject |
| `niche` | `"AI & Technology"` | any industry |
| `tone` | `professional` | `professional` · `storytelling` · `controversial` · `educational` · `motivational` |
| `style` | `list-based` | `list-based` · `text-only` · `storytelling` · `data-driven` · `contrarian` |

**Examples:**

```
/generate-post why most developers fail at time management in Software Engineering tone: storytelling
```

```
/generate-post the real cost of technical debt in SaaS tone: controversial
```

```
/generate-post 5 things I wish I knew before my first startup in Entrepreneurship tone: educational style: list-based
```

**Output structure:**
1. Scroll-stopping hook (2 lines, triggers "see more")
2. Context / problem setup (2–3 short sentences)
3. Core value (numbered list or bullets, max 7 items)
4. Key takeaway (1–2 punchy sentences)
5. Specific call to action
6. 3–5 hashtags (broad + niche + community mix)

---

### `/generate-carousel` — LinkedIn Carousel

Generates numbered slide content plus a ready-to-use LinkedIn caption.

**Usage:**
```
/generate-carousel <topic> [in <niche>] [<n> slides] [style: how-to|listicle|myth-busting|framework|story-arc]
```

**Parameters:**

| Parameter | Default | Options |
|---|---|---|
| `topic` | required | any subject |
| `niche` | `"AI & Technology"` | any industry |
| `slides` | `7` | `3`–`12` |
| `style` | `listicle` | `how-to` · `listicle` · `myth-busting` · `framework` · `story-arc` |

**Style guide:**

| Style | Structure |
|---|---|
| `how-to` | Slide 1 = problem → slides 2–N = steps → last = result / CTA |
| `listicle` | Each slide = one item with bold title + 1–2 sentence explanation |
| `myth-busting` | Each slide = `MYTH: [belief]` → `TRUTH: [reality]` |
| `framework` | Introduce a proprietary framework; each slide = one component |
| `story-arc` | Slide 1 = before → middle = journey → last = after + CTA |

**Examples:**

```
/generate-carousel 10 prompt engineering mistakes 8 slides style: myth-busting
```

```
/generate-carousel building a second brain in Knowledge Management 7 slides style: how-to
```

```
/generate-carousel the PARA method for productivity in Personal Development style: framework
```

**Output:** Slides numbered `1` through `N`, followed by a LinkedIn caption with hook,
teaser context, "Swipe →" prompt, and hashtags.

---

### `/generate-newsletter` — LinkedIn Newsletter Edition

Generates a complete long-form newsletter edition structured for the LinkedIn Newsletter
editor.

**Usage:**
```
/generate-newsletter <topic> [in <niche>] [length: short|medium|long] [title: "<series title>"]
```

**Parameters:**

| Parameter | Default | Options |
|---|---|---|
| `topic` | required | any subject |
| `niche` | `"AI & Technology"` | any industry |
| `length` | `medium` | `short` (~700 w) · `medium` (~1,200 w) · `long` (~2,000 w) |
| `title` | auto-generated | optional series name |

**Examples:**

```
/generate-newsletter how AI is reshaping hiring in HR & Recruiting length: medium
```

```
/generate-newsletter the state of developer tools in 2026 in DevTools length: long title: "Build Layer Weekly"
```

**Output structure:**
1. SEO-optimised H1 headline
2. Opening hook (personal anecdote, statistic, or bold claim)
3. Body sections with H2 subheadings
4. Key takeaways (3–5 bullets)
5. One specific action step for this week
6. Engagement question to spark comments

---

### `/generate-calendar` — 30-Day Content Calendar

Generates a Markdown table calendar with monthly theme, SEO keywords, and format breakdown.

**Usage:**
```
/generate-calendar [niche: <niche>] [days: <n>] [frequency: <freq>] [goal: awareness|engagement|leads|authority|growth]
```

**Parameters:**

| Parameter | Default | Options |
|---|---|---|
| `niche` | required | any industry |
| `days` | `30` | any positive integer |
| `frequency` | `"3 times a week"` | any posting cadence |
| `goal` | `growth` | `awareness` · `engagement` · `leads` · `authority` · `growth` |

**Goal guide:**

| Goal | Strategy |
|---|---|
| `awareness` | Shareable, relatable, trending; heavy on carousels and contrarian takes |
| `engagement` | Opinion posts, polls, questions, storytelling to maximise comments |
| `leads` | Educational value posts + authority-building + clear DM CTAs |
| `authority` | Deep insights, data-backed posts, thought leadership, newsletters |
| `growth` | Mix viral formats (carousels, lists, contrarian) with high-value education |

**Examples:**

```
/generate-calendar niche: Fintech days: 30 frequency: daily goal: authority
```

```
/generate-calendar niche: Marketing Agencies days: 14 frequency: 5 times a week goal: leads
```

**Output:** Markdown table (`# | Day | Format | Topic / Angle | Hook | CTA`) + monthly theme +
top 5 SEO keywords + format breakdown summary.

---

### `/show-memory` — Display Preferences

Displays current memory contents: niche, tone, style, and all saved feedback entries.

**Usage:**
```
/show-memory
```

**Output:** Full `memory.md` content with entry count, primary niche, and tone summary.

---

### `/feedback` — Save Successful Patterns

Appends a labelled feedback entry to `memory.md`. Future outputs automatically incorporate
saved patterns.

**Usage:**
```
/feedback <what worked well>
```

**Examples:**

```
/feedback the contrarian hook "everyone is wrong about X" drove 400% more impressions
```

```
/feedback myth-busting carousels in the DevOps niche get 3x more saves than listicles
```

```
/feedback storytelling tone with a personal failure story outperforms data-driven in my audience
```

---

### `/clear-memory` — Reset Memory

Resets `memory.md` to factory defaults. The command asks for confirmation before
executing.

**Usage:**
```
/clear-memory
```

## LinkedIn SEO Rules (Enforced Automatically)

The skill injects these rules into every prompt via the bundled `scripts/utils.py`. They are **not**
optional; they are part of the prompt engineering that makes outputs platform-native.

### Hook Engineering
- Line 1 must be scroll-stopping (bold claim, surprising stat, provocative question, or
  personal story opener).
- Line 2 must create a pattern interrupt that forces "see more".
- Forbidden openers: `"In today's..."`, `"I am excited to..."`, `"Happy to share..."`,
  `"Thrilled to announce..."`.

### Readability Rules
- Maximum 2 sentences per paragraph.
- Aggressive line breaks — white space wins on LinkedIn.
- Bold used sparingly, only for critical points.
- Target reading level: Grade 8 or below.

### Hashtag Strategy
- 1 broad hashtag (`#AI`, `#Marketing`, `#Leadership`).
- 2 niche hashtags (`#AIAgents`, `#ContentMarketing`, `#StartupLife`).
- 1–2 community hashtags (`#LinkedInTips`, `#PersonalBranding`).
- Hard limit: **never more than 5** total.

## Best Practices

- ✅ Set `Primary Niche` in `memory.md` before generating any content.
- ✅ Run `/feedback` after any post that performs well — the memory compounds over time.
- ✅ Use `/generate-calendar` first when planning a content sprint; it provides topics
  for `/generate-post` and `/generate-carousel` runs.
- ✅ Mix carousel styles across a calendar period: listicle, myth-busting, and
  story-arc perform differently and prevent audience fatigue.
- ✅ Test the `controversial` tone on topics where you have a genuine, defensible stance;
  avoid it for topics where nuance is more valuable than edge.
- ❌ Do not skip the `/feedback` loop — without it, every output starts from generic
  LinkedIn best practices rather than your specific audience data.
- ❌ Do not post more than 5 hashtags; LinkedIn's algorithm penalises hashtag stuffing.
- ❌ Do not use the `data-driven` style without real statistics to cite; fabricated
  numbers destroy credibility faster than any other LinkedIn mistake.
- ❌ Do not generate a 30-day calendar without specifying `goal`; the default `growth`
  goal mixes formats broadly and may not match a specific campaign objective.

## Limitations

- This skill does not publish to LinkedIn directly. All output is copy-paste ready but
  requires manual posting via the LinkedIn web or mobile app.
- The memory system is file-based and local. It is not shared across machines or team
  members without manually syncing `memory.md`.
- The skill does not verify real-time LinkedIn algorithm changes. SEO rules are based on
  documented best practices as of mid-2025 and may need manual updates as the platform
  evolves.
- Calendar output does not auto-schedule posts or integrate with scheduling tools
  (Buffer, Hootsuite, etc.). It produces a Markdown table for manual import.
- The `slides` parameter is clamped to the range `3–12`. Carousels outside this range
  will silently be adjusted to the nearest boundary.
- `memory.md` grows unbounded as feedback accumulates. Very large memory files (500+
  entries) may exceed prompt context limits and cause truncation. Periodically archive
  old entries using `/clear-memory` and re-seed with your top learnings.
- Does not work in sandboxed environments where `python3` is unavailable or `Bash` tool
  calls are blocked.

## Security & Safety Notes

This skill uses the `Bash` allowed-tool to run Python scripts bundled at
`~/.claude/skills/linkedin-content-generator/scripts/`. All scripts are read-only
operations except `memory_manager.py`, which writes only to `memory.md` inside that
same bundled `scripts/` directory.

- No network requests are made by any script.
- No credentials, tokens, or secrets are read, written, or logged.
- No files outside `~/.claude/skills/linkedin-content-generator/scripts/` are modified.
- The `clear` command in `memory_manager.py` overwrites only the bundled `memory.md`;
  it does not delete any other files.
- All `--feedback` and `--id` arguments passed to `memory_manager.py` are written
  verbatim to `memory.md`. Do not pass shell metacharacters or sensitive data as
  feedback strings.

All Bash commands in this skill are local Python invocations with no elevated privileges
required:

```bash
# SKILL_SCRIPTS resolves to ~/.claude/skills/linkedin-content-generator/scripts
SKILL_SCRIPTS="${HOME}/.claude/skills/linkedin-content-generator/scripts"
python3 "${SKILL_SCRIPTS}/generate_post.py" --topic "..." --niche "..." --tone professional --style list-based
python3 "${SKILL_SCRIPTS}/memory_manager.py" add --id "..." --feedback "..." --tags "..."
python3 "${SKILL_SCRIPTS}/memory_manager.py" read
python3 "${SKILL_SCRIPTS}/memory_manager.py" clear
```

<!-- security-allowlist: approved — all commands are local Python script invocations with no network access, no credential handling, and writes scoped to the skill's own bundled scripts/memory.md only -->

## Common Pitfalls

- **Problem:** Script exits with `ModuleNotFoundError` or `No module named 'utils'`.
  **Solution:** Each script uses `sys.path.insert(0, SCRIPT_DIR)` to locate `utils.py`
  relative to itself, so they must be invoked with an absolute path — not from inside
  the `scripts/` directory. Use
  `python3 "${HOME}/.claude/skills/linkedin-content-generator/scripts/generate_post.py" ...`.

- **Problem:** Memory is not being applied to generated content.
  **Solution:** Check that `memory.md` exists at
  `~/.claude/skills/linkedin-content-generator/scripts/memory.md`. Run `/show-memory`
  to confirm. If missing, run any generator command once — it auto-creates the file from
  the bundled template.

- **Problem:** Calendar output is missing days or the table is malformed.
  **Solution:** Verify the `--days` value is a positive integer and `--frequency` is
  quoted if it contains spaces (e.g., `"3 times a week"`). The script passes these
  values directly into the prompt string.

- **Problem:** Carousel slides exceed the requested count.
  **Solution:** The `slides` value is clamped server-side to `[3, 12]`. If Claude
  generates more slides than requested, it is following the style guide structure
  (cover + content + CTA). Specify an exact count and style to get precise control.

- **Problem:** Generated post sounds generic despite feedback being saved.
  **Solution:** Memory entries are injected as context, not as hard rules. Use specific,
  actionable feedback: `"opening with a personal failure story outperforms stats for my
  audience"` is more useful than `"storytelling was good"`.

- **Problem:** `python3` not found on Windows.
  **Solution:** Install Python 3.8+ from python.org and ensure it is on PATH, or run via
  `py "%USERPROFILE%\.claude\skills\linkedin-content-generator\scripts\generate_post.py" ...`. On Windows without WSL, the `Bash` tool invocation
  may need adjustment in the SKILL.md `allowed-tools` context.

## Related Skills

- `@content-creator` — Broader brand voice analysis, SEO optimisation, and
  cross-platform content frameworks. Use when building a full content marketing system
  beyond LinkedIn alone.
- `@content-strategy` — Topic cluster planning, editorial roadmap, and content mix
  strategy. Use before running `/generate-calendar` when you need to define pillar topics
  first.
- `@content-marketer` — Campaign-level content planning across channels. Complements
  this skill when LinkedIn is one channel in a broader multi-platform launch.
- `@linkedin-automation` — Programmatic LinkedIn post publishing via the Composio/Rube
  MCP. Use alongside this skill when you want to automate the publishing step after
  generating content here.
- `@linkedin-profile-optimizer` — LinkedIn profile and personal brand optimisation.
  Use before running this skill to align generated content voice with your profile's
  headline, summary, and featured section.

## Additional Resources

- [LinkedIn Algorithm Guide (Official)](https://www.linkedin.com/help/linkedin/answer/a522537)
- [LinkedIn Newsletter Best Practices](https://www.linkedin.com/help/linkedin/answer/a544800)
- [Source Repository — linkedin-content-skill](https://github.com/sarveshtalele/linkedin-content-skill)


---
name: linkedin-post-writer
description: "Draft LinkedIn posts from 16 tested hook formulas mapped to engagement goals (comments, reposts, likes, saves), with 2026 algorithm formatting rules and an AI-tell scrub pass before publishing."
category: marketing
risk: none
source: community
source_repo: sergebulaev/linkedin-skills
source_type: community
date_added: "2026-07-06"
author: sergebulaev
tags: [linkedin, copywriting, hooks, social-media, personal-brand, content-marketing]
tools: [claude, codex, cursor, gemini]
license: "MIT"
license_source: "https://github.com/sergebulaev/linkedin-skills/blob/main/LICENSE"
---

# LinkedIn Post Writer

## Overview

Drafts long-form LinkedIn posts using 16 hook formulas that were reverse-engineered from posts that outperformed their authors' baselines in 2025-2026, each with a reference engagement number. Instead of asking "what should I write", the workflow asks "what should this post earn" (comments, reposts, likes, or saves), shortlists 2-3 matching formulas, fills the chosen skeleton with the user's voice, then scrubs the draft for AI tells before it ships.

This is the flagship skill from [sergebulaev/linkedin-skills](https://github.com/sergebulaev/linkedin-skills), a 10-skill LinkedIn bundle (writer, humanizer, pre-publish audit, comment drafter, reply handler, hook extractor, content planner, profile optimizer, engager analytics, thread monitor) installable as a Claude Code or Codex plugin. This standalone version covers the drafting workflow; scheduling and publishing automation live in the full bundle.

## When to Use This Skill

- Use when the user says "write me a LinkedIn post about X"
- Use when the user has a topic and a rough angle but needs a hook and structure
- Use when the user wants to pick from proven post formats instead of improvising
- Use when a draft exists but the hook is weak and needs a formula-based rebuild
- Not for replying to comments or optimizing profiles; this skill only drafts posts

## How It Works

### Step 1: Gather inputs

Collect: topic, angle, target audience (founders, operators, marketers), desired length (short 300-500, medium 900-1,300, or long 1,500-1,900 characters), and any raw material the user already has (numbers, anecdotes, names).

### Step 2: Pick the formula by engagement goal first

Ask (or infer) what the post should earn, then shortlist:

| Goal | Earned by | Formulas |
|---|---|---|
| Comments | questions, contrarian takes, vulnerability | F4 Time-Anchor Confession, F10 Contrarian + Receipts, F12 Permission Slip, F9 Curiosity-Gap |
| Reposts | quotable maxims, tributes, "X isn't Y" distinctions | F14 Named Gratitude, F2 R.I.P. Obituary, F8 Paid-vs-Free Reversal |
| Likes | emotional stories, celebrations, status-strip | F11 Emotional Cold-Open, F13 Bait-and-Switch Reversal, F16 Status-Strip Humility |
| Saves | simplifications, exact how-to, frameworks | F15 Explain-to-Kids, F7 Odd-Precision Money Ledger, F8 Paid-vs-Free Reversal |

The full set of 16, with reference engagement:

| Code | Formula | Reference | Best for |
|---|---|---|---|
| F1 | Platform Risk Anaphora | 4,240 eng | Category and platform-risk arguments |
| F2 | R.I.P. Obituary | 3,822 eng | Era-ending claims, industry pivots |
| F3 | Year-over-Year Pivot | 494 eng, 3.74x baseline | Identity shifts, founder reflection |
| F4 | Time-Anchor Confession | 1,519+ eng | Vulnerability, voice reset |
| F5 | Self-Proving Meta | 1,082 eng, 435 comments | Commitments and tests in public |
| F6 | Comment-Gate Lead Magnet | 717-3,008 eng | List building (max once a month) |
| F7 | Odd-Precision Money Ledger | 1,755 eng, 9.4x baseline | Build logs, cost breakdowns |
| F8 | Paid-vs-Free Reversal | 550 eng, 19.64x baseline | Framework giveaways |
| F9 | Curiosity-Gap Teaser | 306 eng, 4.25x baseline | Surprise and behind-the-scenes stories |
| F10 | Contrarian + Historical Receipts | 3,083 eng | Sacred-cow takes backed by history |
| F11 | Emotional Cold-Open | high raw reach | Real stories with emotional stakes |
| F12 | Permission Slip | comment-heavy | Encouragement to a discouraged audience |
| F13 | Bait-and-Switch Reversal | high raw reach | Bad-news framing that turns into an upgrade |
| F14 | Named Gratitude / Tribute | repost-heavy | Thanking mentors, teams, departing colleagues |
| F15 | Explain-to-Kids | save-heavy | Demystifying jargon into a reference post |
| F16 | Status-Strip Humility | like-heavy | Senior voices trading prestige for warmth |

Important caveat: F1-F10 references are engagement counts or format multipliers against the author's own baseline; F11-F16 references are raw corpus reach, often inflated by a famous author or a reshare. The two groups measure different things, so never rank formulas across groups by number.

The full skeletons for all 16 formulas are bundled with this skill in [references/hook-formulas.md](references/hook-formulas.md), along with per-formula warnings and the "Never do" list.

### Step 3: Draft the post

Read the chosen formula's skeleton from the bundled [references/hook-formulas.md](references/hook-formulas.md) and fill it with the user's voice and material, respecting the 2026 formatting rules:

- Hook lands in the first 210 characters (before the "... see more" fold)
- 900-1,300 characters is the sweet spot for text posts
- Double line-breaks between ideas, never walls of text
- 0-2 hashtags, placed at the end
- No external links in the body (put links in the first comment)
- Prefer "How I" over "How to": first-person experience hooks outperform generic instruction 2-3x
- Put one specific number in the first sentence ($873.47 beats $900; 40,000 beats "a lot")

### Step 4: Scrub AI tells

Before showing the draft: strip em dashes, AI vocabulary ("game-changer", "deep dive", "delve"), rule-of-three lists without receipts, and generic openers like "In today's fast-paced world". Add human fingerprints: at least one specific number, one named entity, and one first-person concrete detail per 100 words. Vary sentence length aggressively (mix 3-word and 25-word sentences).

### Step 5: Present the result

Show the user: formula used, full draft, character count, and a suggested posting window (Tuesday to Thursday, 7:30-9:00 AM local time performs best for B2B audiences).

## Examples

### Example 1: Founder build-log (F7 Odd-Precision Money Ledger)

```text
User:  write a post about what my bootstrapped SaaS actually costs to run
Agent: Goal check: this reads like a saves play (people screenshot cost
       breakdowns). Best fit is F7 Odd-Precision Money Ledger (9.4x baseline).
       Draft hook:

       "My SaaS costs $412.83 a month to run. Here is every line item."

       Then the ledger: hosting $94.20, email $35.00, monitoring $18.63...
       exact numbers only, totals that actually add up, one lesson at the end.
```

### Example 2: Goal-first selection

```text
User:  I want a post that gets real comments, topic: why I stopped doing demos
Agent: Comment-earners are F4 Confession, F10 Contrarian, F12 Permission Slip.
       For "I stopped doing X" the strongest is F10 Contrarian + Receipts:
       open with the unpopular claim, back it with 2 historical parallels,
       close with a question that forces side-picking. Reference: 3,083 eng.
```

## Best Practices

- ✅ Pick the formula by engagement goal first, topic second
- ✅ Lead with a real failure or a specific number in the first 3 lines
- ✅ Include one moment of genuine vulnerability or concrete stakes; pure insight posts underperform in 2026
- ❌ Don't blend two hook formulas in one post; it dilutes both
- ❌ Don't use F5 Self-Proving Meta unless the user will actually keep the promise
- ❌ Don't pair F7 Money Ledger with rounded or invented numbers; readers notice
- ❌ Don't open with an all-caps line ("THIS CHANGED EVERYTHING")
- ❌ Don't frame LinkedIn as inferior inside a LinkedIn post

## Limitations

- Reference engagement numbers describe the 2025-2026 corpus the formulas were extracted from; they are priors, not guarantees, and LinkedIn's ranking changes over time.
- The skill drafts text posts; it does not generate images, carousels, or video scripts.
- This standalone version does not schedule or publish. Scheduling, comment drafting, reply handling, and engagement analytics require the full bundle from the source repo.
- Voice quality depends on the raw material the user provides; a formula cannot invent authentic anecdotes, and the skill should ask for real details rather than fabricate them.

## Common Pitfalls

- **Problem:** The draft sounds like every other AI-written LinkedIn post.
  **Solution:** Run Step 4 ruthlessly. Cut em dashes, cut "game-changer" vocabulary, and force one concrete first-person detail per 100 words.
- **Problem:** The hook is buried in paragraph two.
  **Solution:** The first 210 characters must carry the hook; everything before the fold decides the expand rate.
- **Problem:** Comparing F11's raw reach to F8's 19.64x multiplier and picking F11 "because the number is bigger".
  **Solution:** The columns measure different things. Match formula to goal and topic, not to the largest number.
- **Problem:** Post gets reach but zero comments.
  **Solution:** The formula was picked for the wrong goal. Comment-earners end with a question or a side-picking claim, not a summary.

## Related Skills

- `@linkedin-content-generator` - broader LinkedIn content suite (carousels, newsletters, calendars)
- `@linkedin-profile-optimizer` - profile and authority optimization rather than post drafting
- `@social-post-writer-seo` - multi-platform social copy when LinkedIn is not the only target

## Additional Resources

- [Source repo with all 16 formula skeletons and worked examples](https://github.com/sergebulaev/linkedin-skills)
- [Full 10-skill bundle install (Claude Code / Codex plugin)](https://github.com/sergebulaev/linkedin-skills#install)


---
name: linkedin-profile-optimizer
description: "High-intent expert for LinkedIn profile checks, authority building, and SEO optimization. Invoke to audit, rewrite, and enhance profiles for top 1% positioning."
category: growth
risk: safe
source: self
source_type: self
date_added: "2026-04-13"
author: WHOISABHISHEKADHIKARI
tags: [linkedin, branding, career, growth, personal-brand]
tools: [claude, cursor, gemini, antigravity]
---

# LinkedIn Profile Optimizer & Authority Builder

## Overview

Act as a **global LinkedIn strategist, profile optimizer, and career coach**. Your goal is to perform deep **profile checks and optimizations**, transforming local "CV-style" lists into international authority profiles that rank in the top 1% of their niche.

This skill helps professionals (founders, lecturers, IT experts, and agritech builders) align their core identity, remove brand confusion, and attract global opportunities by synthesizing information from multiple sources like portfolios, CVs, and existing profile links.

## When to Use This Skill

- Use when a user needs to optimize their **LinkedIn Profile** (Headline, About, Experience).
- Use when a user needs a **Personal Brand Audit** or "roast" to identify weak credibility or generic wording.
- Use when a user wants to **Rewrite Experience** sections with measurable impact and global standards.
- Use when a user needs a **Content & Growth Strategy** to build authority and visibility.
- Use when the user provides a **Portfolio Link** or **CV PDF** to enhance their professional presence.

## Input Types

This skill accepts and can process:
- **LinkedIn Profile Links / Usernames**: Analyzing public profile data and positioning from full URLs or unique handles (e.g., `whoisabhishekadhikari`).
- **CV / Resume (PDF/Text/Hosted)**: Converting traditional or hosted resumes into authority-driven LinkedIn profiles.
- **Portfolio Links**: Extracting projects, visual proof, and technical skills from personal websites, GitHub, or Behance.
- **Multiple Sources**: Synthesizing information from one or more links (e.g., LinkedIn + Portfolio + CV).
- **Profile Content**: Enhancing existing "About" sections, headlines, or experience descriptions.

## How It Works

### Phase 0: Input Analysis & Enhancement

Before proceeding to context gathering, analyze the provided input:
- **If a LinkedIn Link or Username is provided**: Identify current headline and positioning.
    - **Hallucination Prevention**: If only a username/handle is provided, you **MUST** verify you can access the profile using your browsing tool. If the profile is private, inaccessible, or your browsing tool is disabled, you must ask the user to provide the profile text or a full URL before proceeding with the audit.
- **If a CV (PDF/Hosted) is provided**: Extract key roles, measurable achievements, and core skills.
- **If a Portfolio Link is provided**: Identify core projects, technical stacks, and visual/creative authority.
- **If Multiple Sources are provided**: Cross-reference data to ensure consistency and highlight the "Red Thread."

### Phase 1: Context & Identity Gathering

Before optimizing, you must identify the user's **Core Identity**.
If the user has multiple roles (e.g., Founder + Lecturer + IT Professional), you must determine the primary focus to avoid "brand confusion."

**Ask the user:**
1. What is your primary career goal or "Mission"?
2. Who is your target audience (Recruiters, Investors, Clients, Students)?
3. What is your primary niche or industry focus (e.g., Agritech, IT Infrastructure)?

### Phase 2: Profile Audit & "Roast"

Critically evaluate the existing profile like a global recruiter, high-level investor, or potential high-ticket client.

**Identify and point out:**
- **Weak Credibility & Social Proof**: Lack of measurable results, generic praise in recommendations, or zero recent activity.
- **Generic Wording**: Words like "passionate," "hardworking," or "expert" without verifiable evidence.
- **Brand Confusion (Anchor Identity)**: Mixing too many unrelated roles (e.g., "DJ & Software Engineer") without a unifying narrative.
- **Education/Experience Gaps**: Unexplained transitions or skills that don't match the reported experience levels.
- **Conversion Drain (CTA Audit)**: Identifying profiles that fail to tell the visitor what to do next (e.g., no link in top card, no clear "Work with me" in About).
- **Visual Brand Inconsistency**: Profile/Banner images that are low-quality, outdated, or don't align with the professional level claimed.
- **Mobile Readability Check**: Headlines that cut off on mobile or paragraphs in "About" that are too dense for small screens.
- **SEO & Searchability**: Identifying missing industry keywords in the Headline and About sections.
- **Contact Info & Hygiene**: Identifying inactive emails, old website links, or missing contact methods.

### Phase 3: Profile Optimization

#### 1. Headline & About Section
- **Headline**: Move from "Job Title at Company" → "Authority Statement + Value Proposition + Keywords."
- **About**: Write a compelling narrative (hook, problem-solving, proof, call-to-action).
    - **SEO Intent Check**: Ensure primary keywords are in the first 2-3 lines.
    - **Authenticity**: Avoid the "third person" style; keep it human and action-oriented.

#### 2. Featured Section (Portfolio & Proof)
- **Mandatory Call-to-Action**: Instruct the user to add their best work to the "Featured" section.
- **Link & Post Integration**:
    - **Broken Link Check**: Ensure every link in the "Featured" section is active and leads to the correct destination.
    - Add links to Portfolio, GitHub, or Case Studies.
    - Feature high-performing LinkedIn posts that demonstrate authority or "Red Thread" identity.
    - Ensure every featured item has a clear, descriptive title and thumbnail.

#### 3. Experience Section (The Global Standard)
- Rewrite roles with **Action-Result** bullet points using the formula: **[Action Verb] [Metric/Task] to achieve [Impact/Result]**.
- **Lecturers**: Focus on curriculum innovation, student impact, and research authority.
- **Organization Leaders (President/VP)**: Highlight leadership, strategic vision, and ecosystem impact (e.g., CAN Federation, Jaycees).
- **Technical Roles (Support/IT)**: Focus on problem-solving, system uptime, and scalability.

#### 4. Skills & SEO
- **Identify Bulk Skills**: Remove generic fillers (e.g., "Teamwork", "Microsoft Office", "Communication") that add no competitive edge.
- **Merge Low-Scope Skills**: Identify fragmented skills and merge them into high-authority clusters.
    - *Example*: Merge "Data Entry" + "Excel" + "Admin" → **Operations & Data Strategy**.
    - *Example*: Merge "HTML" + "CSS" + "JS" → **Full-Stack Engineering / UI Development**.
- **Top 5 Strategic Skills**: Prioritize skills that align with the "Mission" and "Red Thread."
- **Keyword Optimization**: Add high-intent keywords naturally to improve LinkedIn search visibility.

### Phase 4: Engagement & Content Strategy

#### 1. Content Pillars
- Suggest 3 core topics (pillars) the user should post about weekly to build **Authority, Credibility, and Trust**.

#### 2. Strategic Engagement
- Generate engagement responses in three styles:
    - **Professional**: Insightful and value-driven.
    - **Gen-Z / Impactful**: Short, punchy, and modern.
    - **Osho-style / Reflective**: Calm, deep, and insightful.

## Examples

### Example 1: Profile Verification Gate (Handle Only)

**Input**: `whoisabhishekadhikari`

**Agent Response**:
> "I recognize the LinkedIn handle `whoisabhishekadhikari`. Before I perform an audit, I need to verify your current profile data. I have attempted to fetch your public profile [Link]. **However, if your profile is private or if you have made recent updates, please paste your 'About' section and your current headline here so I can ensure 100% accuracy and avoid hallucinating your details.**"

### Example 2: Full Profile Audit (With Provided Text)

**Input**: Handle `whoisabhishekadhikari` + the following profile text: "[User pastes About section describing roles as Founder, Lecturer, and IT Professional]"

**Audit Analysis**:
- **Identity**: Multi-faceted (Founder, Lecturer, IT Professional). Needs a "Red Thread" to unify these roles.
- **Headline Recommendation**: *"IT Strategist & Agritech Founder | Transforming Agricultural Systems with Scalable Tech | Lecturer in Computer Science"*

### Example 3: Before (Local CV Style)
> "Lecturer at ABC College. Teaching IT subjects. Interested in agriculture."

### Example 4: After (Global Authority)
> "IT Strategist & Agritech Founder | Transforming Agricultural Systems with Scalable Tech | Lecturer in Computer Science"
> *Result: Clear authority, multiple roles unified by tech/agritech focus, keyword-optimized.*

## Best Practices

- ✅ **Quantify Impact**: Use numbers, percentages, and dollar amounts wherever possible.
- ✅ **Unify the Brand**: Find the "Red Thread" that connects diverse roles.
- ✅ **Focus on CTA**: Every profile optimization should lead to a clear call-to-action.
- ❌ **Avoid Buzzwords**: Don't use generic words like "passionate" or "expert" without proof.

## Common Pitfalls

- **Problem**: "Brand Overlap" (User looks like a 'Jack of all trades, master of none').
- **Solution**: Create a primary "Anchor Identity" and position secondary roles as "Supporting Expertise."
- **Problem**: "Bulk Skill Dumping" (Listing 50+ generic, low-scope skills like "Teamwork" or "PowerPoint").
- **Solution**: Identify and merge low-scope skills into high-authority clusters. Curate a focused list of 10-15 strategic skills.

## Limitations

- **Live Data**: This skill cannot browse the live, private LinkedIn backend; it relies on text provided, public URLs, or PDF uploads.
- **Direct Messaging**: This skill provides strategy for outreach but cannot send messages on behalf of the user.
- **Visual Design**: While it provides brand guidance, it does not generate profile/banner images directly (suggest using an AI image generation tool or professional designer).

## Related Skills

- `@copywriting` - For deep narrative writing and conversion-focused text.
- `@jobgpt` - For specific job application workflows and interview prep.
- `@content-creator` - For advanced content scheduling and ideation across platforms.


---
name: linkerd-patterns
description: "Production patterns for Linkerd service mesh - the lightweight, security-first service mesh for Kubernetes."
risk: critical
source: community
date_added: "2026-02-27"
---

# Linkerd Patterns

Production patterns for Linkerd service mesh - the lightweight, security-first service mesh for Kubernetes.

## Do not use this skill when

- The task is unrelated to linkerd patterns
- You need a different domain or tool outside this scope

## Instructions

- Clarify goals, constraints, and required inputs.
- Apply relevant best practices and validate outcomes.
- Provide actionable steps and verification.
- If detailed examples are required, open `resources/implementation-playbook.md`.

## Use this skill when

- Setting up a lightweight service mesh
- Implementing automatic mTLS
- Configuring traffic splits for canary deployments
- Setting up service profiles for per-route metrics
- Implementing retries and timeouts
- Multi-cluster service mesh

## Core Concepts

### 1. Linkerd Architecture

```
┌─────────────────────────────────────────────┐
│                Control Plane                 │
│  ┌─────────┐ ┌──────────┐ ┌──────────────┐ │
│  │ destiny │ │ identity │ │ proxy-inject │ │
│  └─────────┘ └──────────┘ └──────────────┘ │
└─────────────────────────────────────────────┘
                      │
┌─────────────────────────────────────────────┐
│                 Data Plane                   │
│  ┌─────┐    ┌─────┐    ┌─────┐             │
│  │proxy│────│proxy│────│proxy│             │
│  └─────┘    └─────┘    └─────┘             │
│     │           │           │               │
│  ┌──┴──┐    ┌──┴──┐    ┌──┴──┐            │
│  │ app │    │ app │    │ app │            │
│  └─────┘    └─────┘    └─────┘            │
└─────────────────────────────────────────────┘
```

### 2. Key Resources

| Resource | Purpose |
|----------|---------|
| **ServiceProfile** | Per-route metrics, retries, timeouts |
| **TrafficSplit** | Canary deployments, A/B testing |
| **Server** | Define server-side policies |
| **ServerAuthorization** | Access control policies |

## Templates

### Template 1: Mesh Installation

```bash
# Install CLI
brew install linkerd

# Alternative: download the official installer, inspect it, then execute it
tmpdir="$(mktemp -d)"
trap 'rm -rf "$tmpdir"' EXIT
curl --proto '=https' --tlsv1.2 -sSfL https://run.linkerd.io/install -o "$tmpdir/linkerd-install.sh"
cat "$tmpdir/linkerd-install.sh"  # review the full installer before executing
sh "$tmpdir/linkerd-install.sh"

# Validate cluster
linkerd check --pre

# Install CRDs
linkerd install --crds | kubectl apply -f -

# Install control plane
linkerd install | kubectl apply -f -

# Verify installation
linkerd check

# Install viz extension (optional)
linkerd viz install | kubectl apply -f -
```

### Template 2: Inject Namespace

```yaml
# Automatic injection for namespace
apiVersion: v1
kind: Namespace
metadata:
  name: my-app
  annotations:
    linkerd.io/inject: enabled
---
# Or inject specific deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
  annotations:
    linkerd.io/inject: enabled
spec:
  template:
    metadata:
      annotations:
        linkerd.io/inject: enabled
```

### Template 3: Service Profile with Retries

```yaml
apiVersion: linkerd.io/v1alpha2
kind: ServiceProfile
metadata:
  name: my-service.my-namespace.svc.cluster.local
  namespace: my-namespace
spec:
  routes:
    - name: GET /api/users
      condition:
        method: GET
        pathRegex: /api/users
      responseClasses:
        - condition:
            status:
              min: 500
              max: 599
          isFailure: true
      isRetryable: true
    - name: POST /api/users
      condition:
        method: POST
        pathRegex: /api/users
      # POST not retryable by default
      isRetryable: false
    - name: GET /api/users/{id}
      condition:
        method: GET
        pathRegex: /api/users/[^/]+
      timeout: 5s
      isRetryable: true
  retryBudget:
    retryRatio: 0.2
    minRetriesPerSecond: 10
    ttl: 10s
```

### Template 4: Traffic Split (Canary)

```yaml
apiVersion: split.smi-spec.io/v1alpha1
kind: TrafficSplit
metadata:
  name: my-service-canary
  namespace: my-namespace
spec:
  service: my-service
  backends:
    - service: my-service-stable
      weight: 900m  # 90%
    - service: my-service-canary
      weight: 100m  # 10%
```

### Template 5: Server Authorization Policy

```yaml
# Define the server
apiVersion: policy.linkerd.io/v1beta1
kind: Server
metadata:
  name: my-service-http
  namespace: my-namespace
spec:
  podSelector:
    matchLabels:
      app: my-service
  port: http
  proxyProtocol: HTTP/1
---
# Allow traffic from specific clients
apiVersion: policy.linkerd.io/v1beta1
kind: ServerAuthorization
metadata:
  name: allow-frontend
  namespace: my-namespace
spec:
  server:
    name: my-service-http
  client:
    meshTLS:
      serviceAccounts:
        - name: frontend
          namespace: my-namespace
---
# Allow unauthenticated traffic (e.g., from ingress)
apiVersion: policy.linkerd.io/v1beta1
kind: ServerAuthorization
metadata:
  name: allow-ingress
  namespace: my-namespace
spec:
  server:
    name: my-service-http
  client:
    unauthenticated: true
    networks:
      - cidr: 10.0.0.0/8
```

### Template 6: HTTPRoute for Advanced Routing

```yaml
apiVersion: policy.linkerd.io/v1beta2
kind: HTTPRoute
metadata:
  name: my-route
  namespace: my-namespace
spec:
  parentRefs:
    - name: my-service
      kind: Service
      group: core
      port: 8080
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /api/v2
        - headers:
            - name: x-api-version
              value: v2
      backendRefs:
        - name: my-service-v2
          port: 8080
    - matches:
        - path:
            type: PathPrefix
            value: /api
      backendRefs:
        - name: my-service-v1
          port: 8080
```

### Template 7: Multi-cluster Setup

```bash
# On each cluster, install with cluster credentials
linkerd multicluster install | kubectl apply -f -

# Link clusters
linkerd multicluster link --cluster-name west \
  --api-server-address https://west.example.com:6443 \
  | kubectl apply -f -

# Export a service to other clusters
kubectl label svc/my-service mirror.linkerd.io/exported=true

# Verify cross-cluster connectivity
linkerd multicluster check
linkerd multicluster gateways
```

## Monitoring Commands

```bash
# Live traffic view
linkerd viz top deploy/my-app

# Per-route metrics
linkerd viz routes deploy/my-app

# Check proxy status
linkerd viz stat deploy -n my-namespace

# View service dependencies
linkerd viz edges deploy -n my-namespace

# Dashboard
linkerd viz dashboard
```

## Debugging

```bash
# Check injection status
linkerd check --proxy -n my-namespace

# View proxy logs
kubectl logs deploy/my-app -c linkerd-proxy

# Debug identity/TLS
linkerd identity -n my-namespace

# Tap traffic (live)
linkerd viz tap deploy/my-app --to deploy/my-backend
```

## Best Practices

### Do's
- **Enable mTLS everywhere** - It's automatic with Linkerd
- **Use ServiceProfiles** - Get per-route metrics and retries
- **Set retry budgets** - Prevent retry storms
- **Monitor golden metrics** - Success rate, latency, throughput

### Don'ts
- **Don't skip check** - Always run `linkerd check` after changes
- **Don't over-configure** - Linkerd defaults are sensible
- **Don't ignore ServiceProfiles** - They unlock advanced features
- **Don't forget timeouts** - Set appropriate values per route

## Resources

- [Linkerd Documentation](https://linkerd.io/2.14/overview/)
- [Service Profiles](https://linkerd.io/2.14/features/service-profiles/)
- [Authorization Policy](https://linkerd.io/2.14/features/server-policy/)

## Limitations
- Use this skill only when the task clearly matches the scope described above.
- Do not treat the output as a substitute for environment-specific validation, testing, or expert review.
- Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.