Skip to main content
Glama
condr-at

linkedin-local-mcp

by condr-at
README.md
# linkedin-local-mcp

A deliberately small, local-only MCP server for LinkedIn's **official API**. It does not scrape LinkedIn, use Voyager endpoints, automate a browser, send telemetry, or expose access tokens as MCP tool arguments.

## Features

- OAuth 2.0 authorization with CSRF `state` validation
- access token stored in the operating-system keychain
- identify the authenticated member
- publish text posts with explicit confirmation
- read comments when the LinkedIn app has the required read permission
- reply to a specific comment with explicit confirmation
- conservative API surface: no raw-request passthrough

## Important LinkedIn permission limits

Ordinary self-service apps can request OpenID Connect and posting permissions. Reading member social content may require a restricted LinkedIn permission granted only to selected developers. The MCP tool can read comments only when LinkedIn has granted the corresponding permission to your app; otherwise the official API returns `403`.

This project intentionally does not work around that restriction with scraping or browser automation.

## Requirements

- Python 3.11+
- [uv](https://docs.astral.sh/uv/)
- a [LinkedIn Developer App](https://www.linkedin.com/developers/apps)
- the **Sign In with LinkedIn using OpenID Connect** and **Share on LinkedIn** products

Add this exact redirect URL to the app's authorized redirect URLs:

```text
http://127.0.0.1:8765/callback
```

## Install and authenticate

```bash
git clone https://github.com/condr-at/linkedin-local-mcp.git
cd linkedin-local-mcp
uv sync --no-editable

uv run linkedin-local-mcp-auth
```

The command prompts for the Client ID and then requests the Client Secret using hidden terminal input, so neither value is stored in shell history. The secret is needed only during authorization. The resulting access token is stored in the OS keychain under `linkedin-local-mcp/default` and is never written to the repository or MCP configuration.

LinkedIn access tokens normally expire after roughly 60 days. Run the auth command again when needed.

## Hermes Agent configuration

Use Hermes' native local stdio MCP support. Add the server through Hermes configuration mechanisms with the equivalent of:

```yaml
mcp_servers:
  linkedin_local:
    command: uvx
    args:
      - --from
      - /absolute/path/to/linkedin-local-mcp
      - linkedin-local-mcp
    sampling:
      enabled: false
```

Restart Hermes after adding the server. Tools appear with the `mcp_linkedin_local_` prefix.

Do not add LinkedIn tokens or client secrets to this configuration.

## Tools

| Tool | Behavior |
|---|---|
| `linkedin_auth_status` | Validate the token and identify its member |
| `linkedin_publish_post` | Publish a text post; requires `confirmed=true` |
| `linkedin_list_comments` | Read comments, subject to LinkedIn permissions |
| `linkedin_reply_to_comment` | Reply to a specific comment; requires `confirmed=true` |

The narrow tool set is intentional. Drafting and scheduling belong in the agent; this server only performs official LinkedIn API operations.

## Development

```bash
uv sync --extra dev
uv run python -m pytest
uv run ruff check .
```

## Security

- Review every requested LinkedIn product and permission.
- Never paste access tokens into chat or pass them as tool arguments.
- Keep human confirmation enabled for all writes.
- Never use this project for scraping, bulk outreach, invitations, or automated job applications.
- Report vulnerabilities through GitHub private vulnerability reporting.

## License

MIT

TDQS

A3.7/5.0

Scored across 4 tools

Disambiguation5/5

Each tool targets a clearly distinct concern: authentication, publishing, reading comments, and replying to comments. There is no meaningful overlap between read and write operations or between posts and comments.

Naming Consistency4/5

Most tools follow a consistent linkedin_verb_noun pattern (publish_post, list_comments, reply_to_comment). linkedin_auth_status is a slight deviation because it uses a noun phrase rather than an explicit verb like get or check.

Tool Count4/5

Four tools is a compact but reasonable set for a focused LinkedIn posting and comment engagement workflow. It is not overly thin given the apparent scope, though it stays at the smaller end of the typical range.

Completeness4/5

The core workflow of checking auth, publishing a post, viewing comments, and replying is covered without obvious dead ends. However, there is no way to fetch a user's own posts, update/delete a post, or delete a comment, which are minor gaps for a fuller LinkedIn integration.

Maintenance

ActivityMaintained
ResponsivenessNo issues