vielhuber / linkedinmcp
Minimal PHP helper and MCP server for LinkedIn posting and member data portability.
Requires
- php: ^8.5
- ext-curl: *
- ext-json: *
- vielhuber/simplemcp: ^1.1.7
Requires (Dev)
None
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
one small php helper and mcp server for linkedin posting and your own member data. two apps, separate tokens, one tool set.
php
composer require vielhuber/linkedinmcp
use vielhuber\linkedinmcp\linkedinmcp; $linkedin = new linkedinmcp(); $linkedin->profile(); $linkedin->snapshot(domain: 'PROFILE', start: 0); $linkedin->posts(start: 0); $linkedin->activity(startTime: $processedAt, count: 10); $linkedin->memberAuthorization(); $linkedin->createPost(text: 'your approved text'); $linkedin->updatePost(postUrn: $postUrn, text: 'your approved replacement'); $linkedin->deletePost(postUrn: $postUrn); $linkedin->uploadImage(filePath: '/absolute/path/to/image.png'); $linkedin->uploadVideo(filePath: '/absolute/path/to/video.mp4'); $linkedin->videoStatus(videoUrn: $mediaUrn);
two separate apps and tokens:
| app | token environment variable | scopes |
|---|---|---|
| posting: openid connect + share on linkedin | LINKEDIN_POSTING_ACCESS_TOKEN |
openid profile w_member_social |
| member data portability api (member) | LINKEDIN_MEMBER_ACCESS_TOKEN |
r_dma_portability_self_serve |
member access is region-dependent and limited to the app administrator's own data. keep both apps' identities separate. api versions: posting 202610, member 202312; override with LINKEDIN_POSTING_VERSION / LINKEDIN_MEMBER_VERSION.
php oauth: one Authorization(clientId: ..., clientSecret: ..., redirectUri: ...) per app; url($state, $scopes), verify state, exchangeCode($code). refresh only with an issued refresh token. oauth helpers are not mcp tools.
- snapshots: page index
start; no-data response is http 404. no home feed. - activity: 28 days after consent; cursor
processedAt, deduplicateactivityId, poll at most hourly. - uploads return
id, not a post; videos must beAVAILABLE. image processing checks may require extra permissions. - approve writes first. edits change commentary only; use exact share/ugcpost urns. never blindly retry uncertain writes.
mcp
{
"mcpServers": {
"linkedin": {
"command": "php",
"args": ["/absolute/path/to/vendor/bin/mcp-server.php"],
"env": {
"LINKEDIN_POSTING_ACCESS_TOKEN": "your-posting-access-token",
"LINKEDIN_MEMBER_ACCESS_TOKEN": "your-member-access-token"
}
}
}
}
11 tools; php methods become snake_case tool names. stdio is private. http requires https and MCP_TOKEN.