LinkedIn HTTP MCP Server
README.md
# LinkedIn HTTP MCP Server
A production-ready HTTP/Streamable Model Context Protocol (MCP) server for LinkedIn. It supports both **Streamable HTTP** (recommended) and Server-Sent Events (SSE) transports. It is designed to be directly deployable to Render and registered as a Custom Connector on Grok.
This project preserves and reuses the exact LinkedIn business logic and authentication flow from the original `felipfr/linkedin-mcpserver` repository, replacing only the stdio bootstrap layer with a dual-compatible HTTP/SSE/Streamable Express subsystem.
## Features
- **Standard HTTP Transport:** Exposes standard endpoints compliant with the latest `@modelcontextprotocol/sdk`.
- **Dual Transport Support:** Automatically negotiates Streamable HTTP (GET/POST/DELETE `/mcp`) and Legacy SSE (GET `/sse`, POST `/messages`).
- **Production Routing:** Built on a robust, graceful, and session-managed Express.js platform supporting multiple concurrent clients.
- **Render Deployment Ready:** Dynamic port binding, Dockerfile, and `render.yaml` blueprint included.
- **Graceful Shutdown:** Cleans up active client transports and terminates connections cleanly.
- **Structured Logging:** Powered by Pino structured logger.
- **Environment Validation:** Strict environment checking at startup using Zod.
---
## Exposed MCP Tools
The server registers and runs the following LinkedIn tools with identical behavior and interfaces as the original:
1. **`search-jobs`**: Search for LinkedIn job postings.
2. **`search-people`**: Search for profiles based on keywords, locations, current companies, and industries.
3. **`get-profile`**: Retrieve detail on a profile by Public ID or URN ID.
4. **`get-my-profile`**: Fetch detail on the authenticated user's profile.
5. **`get-network-stats`**: Fetch network size statistics for the authenticated user.
6. **`get-connections`**: Retrieve a list of connections.
7. **`send-message`**: Send a connection message.
---
## Setup & Environment Variables
Create a `.env` file in the project root:
```bash
cp .env.example .env
```
Define the following environment variables:
| Variable | Description | Default |
| --- | --- | --- |
| `PORT` | HTTP Server Port (Render overrides this dynamically) | `5050` |
| `LOG_LEVEL` | Logging level (`trace`, `debug`, `info`, `warn`, `error`) | `info` |
| `MCP_SERVER_NAME` | The identifier name of this MCP server | `linkedin-mcp-http` |
| `MCP_SERVER_VERSION`| The version of this MCP server | `1.0.0` |
| `LINKEDIN_CLIENT_ID` | **Required.** LinkedIn developer app client ID | None |
| `LINKEDIN_CLIENT_SECRET` | **Required.** LinkedIn developer app client secret | None |
> Get your client ID and secret from the [LinkedIn Developer Portal](https://www.linkedin.com/developers/apps).
>
> [!WARNING]
> By default, standard self-serve LinkedIn Developer Apps do not have access to private endpoints like `/search/people`, `/connections`, `/messages`, or `/jobs`. Your LinkedIn Developer App must be approved for special Partner Programs (e.g., Talent Solutions, Sales Navigator, or Community Management) to access these endpoints, or you will encounter `403 Forbidden` errors during execution.
---
## Local Development
### 1. Install Dependencies
```bash
npm install
```
### 2. Run in Development Mode
Builds and watches typescript code in real-time:
```bash
npm run dev
```
### 3. Build & Run in Production Mode
```bash
npm run build
npm start
```
---
## Grok Custom Connector Setup
Once deployed to a public URL (e.g. `https://your-app.onrender.com`), configure it on Grok:
1. Go to [grok.com/connectors](https://grok.com/connectors).
2. Click **"New Connector"**.
3. Choose **"Custom"**.
4. Enter your MCP Server URL. Grok supports Streamable HTTP and SSE:
- For Streamable HTTP: `https://your-app.onrender.com/mcp`
- For Legacy SSE: `https://your-app.onrender.com/sse`
5. Click **"Save"**. Grok will auto-discover the tools and expose them in your chat session!
---
## Deploying to Render
Deploying to Render requires no code changes:
1. Push this codebase to a GitHub repository.
2. In the Render Dashboard, click **"New"** -> **"Blueprint"** (or Web Service).
3. Connect your repository. Render will automatically detect the `render.yaml` configuration.
4. Input your `LINKEDIN_CLIENT_ID` and `LINKEDIN_CLIENT_SECRET` environment variables.
5. Click **"Deploy"**.
---
## Troubleshooting
- **Server fails on boot:** Ensure that your `.env` contains valid non-empty `LINKEDIN_CLIENT_ID` and `LINKEDIN_CLIENT_SECRET` values.
- **API Request Errors:** Check console logs. If you get `401 Unauthorized` or token errors, verify your credentials on the LinkedIn Developer Portal and ensure your application is approved for the relevant scopes.
- **Port Conflict:** If port `5050` is in use locally, define `PORT=6060` (or any other number) in your `.env`.
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues