PostPost

Tools Reference

Complete reference for all 18 active PostPost MCP tools with parameters, examples, and code snippets. Three additional tools (linkedin_posts, linkedin_post_comments, linkedin_post_reactions) are temporarily disabled pending LinkedIn approval of the r_member_social permission — see LinkedIn Feed Retrieval Tools below.

Note: Most tools return the full { success, ... } backend API response as shown in the examples below. A few tools — list_connections, list_workspace_users, and create_workspace_user — return a different response shape (e.g., an array or object without the success wrapper) because the underlying API endpoints use a different response format. The MCP server does not do any post-processing on responses. The response examples below reflect the actual format returned by each tool.

Posts Tools

list_posts

List posts with optional filters for status, platform, and date range.

Parameters:

ParameterTypeRequiredDescription
statusstringNoFilter by status: draft, scheduled, published, failed, partially_published
platformstringNoFilter by platform: twitter, linkedin, instagram, threads, tiktok, youtube, facebook, bluesky, mastodon, telegram
fromDatestringNoStart date (ISO 8601): 2026-02-01T00:00:00Z
toDatestringNoEnd date (ISO 8601): 2026-02-28T23:59:59Z
pagenumberNoPage number (default: 1)
limitnumberNoResults per page (default: 20, max: 100)
sortBystringNoSort field: createdAt, updatedAt, scheduledTime (default: createdAt)
sortOrderstringNoSort direction: asc or desc (default: desc)

Example prompts:

"Show my scheduled posts"
"List all posts from last week"
"What LinkedIn posts are scheduled for next month?"
"Show me failed posts"
"List my drafts"

Python example:

import asyncio
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client

async def list_scheduled_posts():
    headers = {"Authorization": "Bearer sk_YOUR_API_KEY"}

    async with streamablehttp_client("https://mcp.postpost.dev", headers=headers) as (read, write, _):
        async with ClientSession(read, write) as session:
            await session.initialize()

            # List scheduled posts
            result = await session.call_tool("list_posts", {
                "status": "scheduled",
                "limit": 50
            })
            print(result.content[0].text)

asyncio.run(list_scheduled_posts())

Response example:

{
  "success": true,
  "posts": [
    {
      "postGroupId": "67a1b2c3d4e5f6a7b8c9d0e1",
      "content": "Excited to share our latest update!",
      "status": "scheduled",
      "scheduledTime": "2026-02-20T14:00:00Z",
      "platforms": [
        {
          "platformId": "linkedin-123456",
          "platform": "linkedin",
          "status": "scheduled"
        }
      ],
      "createdAt": "2026-02-19T10:30:00Z",
      "updatedAt": "2026-02-19T10:30:00Z",
      "mediaUrls": []
    }
  ],
  "pagination": {
    "totalItems": 1,
    "totalPages": 1,
    "page": 1,
    "limit": 20,
    "hasNextPage": false,
    "hasPrevPage": false
  }
}

create_post

Create and schedule a post to one or more platforms.

Parameters:

ParameterTypeRequiredDescription
contentstringYesPost text content
platformsstring[]YesArray of platform connection IDs (from list_connections)
scheduledTimestringYesWhen to publish (ISO 8601): 2026-03-01T14:00:00Z

MCP vs REST difference: scheduledTime is required in the MCP schema to ensure AI agents always specify a publish time. In the REST API, this field is optional — omitting it creates a draft post instead.

MCP limitation: platformSettings is NOT available via MCP. To configure platform-specific settings (TikTok privacy level, YouTube title, Instagram videoType, Threads replyControl), use the REST API directly.

platformSettings schema reference — only these 4 platforms support settings; settings for other platforms are silently ignored:

{
  "platformSettings": {
    "tiktok": {
      "viewerSetting": "string",
      "commercialContent": "boolean",
      "brandOrganic": "boolean",
      "brandedContent": "boolean",
      "allowComments": "boolean",
      "allowDuet": "boolean",
      "allowStitch": "boolean"
    },
    "instagram": {
      "videoType": "REELS | STORIES"  // default: "REELS"
    },
    "youtube": {
      "privacy": "public | unlisted | private",  // default: "public"
      "title": "string"  // default: ""
    },
    "threads": {
      "replyControl": "string"  // default: ""
    }
  }
}

Example prompts:

"Schedule 'Hello world!' to LinkedIn for tomorrow at 9am"
"Post 'We're hiring!' to Twitter and LinkedIn right now"
"Schedule this announcement to all my accounts for Monday"

Python example:

import asyncio
from datetime import datetime, timedelta
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client

async def schedule_post():
    headers = {"Authorization": "Bearer sk_YOUR_API_KEY"}

    async with streamablehttp_client("https://mcp.postpost.dev", headers=headers) as (read, write, _):
        async with ClientSession(read, write) as session:
            await session.initialize()

            # First get connections to find platform IDs
            connections = await session.call_tool("list_connections", {})

            # Schedule a post for tomorrow at 9am UTC
            tomorrow_9am = (datetime.utcnow() + timedelta(days=1)).replace(
                hour=9, minute=0, second=0, microsecond=0
            ).isoformat() + "Z"

            result = await session.call_tool("create_post", {
                "content": "Excited to share our latest product update!",
                "platforms": ["linkedin-abc123"],
                "scheduledTime": tomorrow_9am
            })
            print(result.content[0].text)

asyncio.run(schedule_post())

Response example:

{
  "success": true,
  "postGroupId": "67a1b2c3d4e5f6a7b8c9d0e1"
}

LinkedIn Mentions:

You can @mention people and companies in LinkedIn posts using this syntax in your content:

@{urn:li:person:12345678|John Doe}           # Mention a person
@{urn:li:organization:12345678|Acme Corp Inc}  # Mention a company

Example:

"Great insights from @{urn:li:person:12345678|John Doe} at @{urn:li:organization:12345678|Acme Corp}!"

Important: The display name must exactly match the LinkedIn profile name (case-sensitive), including company suffixes like "Inc", "LLC", etc.

Platform limits:

PlatformCharactersImagesVideoSpecial Features
LinkedIn3,00010500MBDocuments, @mentions
X/Twitter280 (25K premium)4120sAuto-threading
Instagram2,200103 min (180s) Reels, 60s carouselReels & Stories supported
Threads500 (10,000 with text attachment)105minAuto-threading
TikTok2,200N/A10minVideo-only platform
YouTube5,000 descN/A12hShorts support
Facebook63,2061045minPage posts, Reels
Bluesky30043 min / 100 MBAuto-facet detection
Mastodon500*4~99 MBInstance-variable
Telegram4,096 (1,024 captions)Unlimited2GBMarkdown/HTML support

*Varies by instance

Note: LinkedIn's "10 images" is the multi-image upload limit, not a carousel. Organic carousels on LinkedIn are not supported via the API (carousels are only available for sponsored/ad content). To share multi-page content organically, use LinkedIn document (PDF) posts instead.

Note: Multi-threaded nested posts on Threads are temporarily unavailable. Single posts and carousel posts to Threads continue to work normally.


get_post

Get details of a specific post group.

Parameters:

ParameterTypeRequiredDescription
postGroupIdstringYesPost group ID (e.g., 67a1b2c3d4e5f6a7b8c9d0e1)

Example prompts:

"Show me the details of post 67a1b2c3d4e5f6a7b8c9d0e1"
"What's the status of my last scheduled post?"
"Get info about my recent post"

Python example:

async def get_post_details():
    headers = {"Authorization": "Bearer sk_YOUR_API_KEY"}

    async with streamablehttp_client("https://mcp.postpost.dev", headers=headers) as (read, write, _):
        async with ClientSession(read, write) as session:
            await session.initialize()

            result = await session.call_tool("get_post", {
                "postGroupId": "67a1b2c3d4e5f6a7b8c9d0e1"
            })
            print(result.content[0].text)

Response example:

{
  "success": true,
  "postGroupId": "67a1b2c3d4e5f6a7b8c9d0e1",
  "posts": [
    {
      "platformId": "linkedin-abc123",
      "platform": "linkedin",
      "status": "scheduled",
      "content": "Excited to share our latest update!",
      "postedId": null,
      "error": null
    }
  ]
}

Note: The get_post response returns per-platform post fields (platform, platformId, content, status, postedId, error) — not scheduledTime. The scheduledTime is a post-group-level field available via list_posts.


update_post

Reschedule or change post status.

Parameters:

ParameterTypeRequiredDescription
postGroupIdstringYesPost group ID
statusstringNoNew status: draft or scheduled
scheduledTimestringNoNew scheduled time (ISO 8601)

Note: At least one of status or scheduledTime must be provided, otherwise the backend returns a 400 error.

Example prompts:

"Reschedule post 67a1b2c3d4e5f6a7b8c9d0e1 to Friday at 3pm"
"Change my draft to scheduled"
"Move tomorrow's post to next week"
"Update the post to publish at 10am instead"

Python example:

async def reschedule_post():
    headers = {"Authorization": "Bearer sk_YOUR_API_KEY"}

    async with streamablehttp_client("https://mcp.postpost.dev", headers=headers) as (read, write, _):
        async with ClientSession(read, write) as session:
            await session.initialize()

            result = await session.call_tool("update_post", {
                "postGroupId": "67a1b2c3d4e5f6a7b8c9d0e1",
                "scheduledTime": "2026-03-01T15:00:00Z"
            })
            print(result.content[0].text)

Response example:

{
  "success": true,
  "message": "Post updated successfully",
  "postGroup": {
    "_id": "67a1b2c3d4e5f6a7b8c9d0e1",
    "status": "scheduled",
    "scheduledTime": "2026-03-01T15:00:00Z"
  }
}

Note: The scheduledTime field in the response is only included when the post has a scheduled time set. Draft posts without a scheduled time will omit this field.

Note: Only posts with status draft or scheduled can be updated. Attempting to update a post in any other status (e.g., published, failed, partially_published) returns a 400 error: "Cannot update post: post is currently in {status} status".


delete_post

Delete a post from all platforms.

Parameters:

ParameterTypeRequiredDescription
postGroupIdstringYesPost group ID to delete

Example prompts:

"Delete post 67a1b2c3d4e5f6a7b8c9d0e1"
"Cancel my scheduled post for tomorrow"
"Remove all my draft posts"

Python example:

async def delete_post():
    headers = {"Authorization": "Bearer sk_YOUR_API_KEY"}

    async with streamablehttp_client("https://mcp.postpost.dev", headers=headers) as (read, write, _):
        async with ClientSession(read, write) as session:
            await session.initialize()

            result = await session.call_tool("delete_post", {
                "postGroupId": "67a1b2c3d4e5f6a7b8c9d0e1"
            })
            print(result.content[0].text)

Response example:

{
  "success": true
}

get_upload_url

Get a presigned URL to upload media files.

Parameters:

ParameterTypeRequiredDescription
postGroupIdstringYesPost group ID to attach media to
fileNamestringYesFile name (e.g., photo.jpg)
contentTypestringYesMIME type (e.g., image/jpeg, video/mp4)
typestringYesMedia type: image or video

Supported formats:

TypeFormats
ImagesJPEG, PNG, GIF, WebP
VideosMP4, MOV, AVI, WebM

Python example:

import aiohttp

async def upload_image_to_post():
    headers = {"Authorization": "Bearer sk_YOUR_API_KEY"}

    async with streamablehttp_client("https://mcp.postpost.dev", headers=headers) as (read, write, _):
        async with ClientSession(read, write) as session:
            await session.initialize()

            # Get upload URL
            result = await session.call_tool("get_upload_url", {
                "postGroupId": "67a1b2c3d4e5f6a7b8c9d0e1",
                "fileName": "product-photo.jpg",
                "contentType": "image/jpeg",
                "type": "image"
            })

            # Parse the response - contains uploadUrl, fileUrl, and mediaId
            # Response: { "success": true, "uploadUrl": "https://...", "fileUrl": "https://...", "mediaId": "..." }
            import json
            data = json.loads(result.content[0].text)
            upload_url = data["uploadUrl"]

            # Upload file using the presigned URL
            async with aiohttp.ClientSession() as http:
                with open("product-photo.jpg", "rb") as f:
                    await http.put(upload_url, data=f.read())

Connections Tool

list_connections

List all connected social media accounts.

Parameters: None

Example prompts:

"Show my connected accounts"
"What platforms am I connected to?"
"List my social media accounts"
"Which accounts do I have linked?"

Python example:

async def list_connections():
    headers = {"Authorization": "Bearer sk_YOUR_API_KEY"}

    async with streamablehttp_client("https://mcp.postpost.dev", headers=headers) as (read, write, _):
        async with ClientSession(read, write) as session:
            await session.initialize()

            result = await session.call_tool("list_connections", {})
            print(result.content[0].text)

asyncio.run(list_connections())

Response example:

[
  {
    "platformId": "twitter-123456789",
    "username": "@yourcompany",
    "displayName": "Your Company",
    "profileImageUrl": "https://pbs.twimg.com/profile_images/...",
    "profileUrl": null,
    "tokenStatus": "unknown",
    "tokenExpiresIn": null,
    "accessTokenExpiresAt": null,
    "lastSuccessfulPost": null,
    "lastError": null
  },
  {
    "platformId": "linkedin-Tz9W5i6ZYG",
    "username": "Your Company Page",
    "displayName": "Your Company",
    "profileImageUrl": "https://media.licdn.com/...",
    "profileUrl": "https://www.linkedin.com/company/your-company",
    "tokenStatus": "valid",
    "tokenExpiresIn": "82d 4h",
    "accessTokenExpiresAt": "2026-06-15T12:00:00.000Z",
    "lastSuccessfulPost": "2026-03-10T09:30:00.000Z",
    "lastError": null
  }
]

Response fields:

FieldTypeDescription
platformIdstringUnique ID for creating posts (e.g., twitter-123456789)
usernamestringPlatform username or handle
displayNamestringDisplay name on the platform
profileImageUrlstringProfile image URL
profileUrlstring/nullURL to the profile on the platform
tokenStatusstringToken health: valid, expiring_soon, expired, unknown
tokenExpiresInstring/nullHuman-readable time until expiration (e.g., "7d 3h")
accessTokenExpiresAtstring/nullISO 8601 timestamp when the access token expires
lastSuccessfulPoststring/nullISO 8601 timestamp of the last successful post via this connection
lastErrorobject/nullLast error details: { message: string, occurredAt: string }

LinkedIn Analytics Tools

linkedin_post_stats

Get engagement metrics for a specific LinkedIn post.

Parameters:

ParameterTypeRequiredDescription
postedIdstringYesLinkedIn post URN (e.g., urn:li:share:123456)
platformIdstringYesPlatform connection ID
queryTypesstring[]NoMetrics to fetch: IMPRESSION, REACTION, COMMENT, SHARE (the backend may accept additional types)

Example prompts:

"How did my last LinkedIn post perform?"
"Get impressions for my LinkedIn post"
"Show engagement on my recent LinkedIn update"
"What's the reach of my LinkedIn announcement?"

Python example:

async def get_linkedin_post_stats():
    headers = {"Authorization": "Bearer sk_YOUR_API_KEY"}

    async with streamablehttp_client("https://mcp.postpost.dev", headers=headers) as (read, write, _):
        async with ClientSession(read, write) as session:
            await session.initialize()

            result = await session.call_tool("linkedin_post_stats", {
                "postedId": "urn:li:share:7123456789",
                "platformId": "linkedin-abc123",
                "queryTypes": ["IMPRESSION", "REACTION", "COMMENT", "SHARE"]
            })
            print(result.content[0].text)

Response example:

{
  "impressions": 1250,
  "uniqueImpressions": 680,
  "reactions": 28,
  "comments": 5,
  "shares": 3,
  "engagementRate": 2.9
}

linkedin_account_stats

Get aggregated statistics for your LinkedIn account.

Parameters:

ParameterTypeRequiredDescription
platformIdstringYesPlatform connection ID
queryTypesstring[]NoMetrics to fetch
aggregationstringNoDAILY or TOTAL (default: TOTAL)

Example prompts:

"Show my LinkedIn analytics"
"What's my total engagement on LinkedIn?"
"Give me daily LinkedIn stats for this week"

Python example:

async def get_linkedin_account_stats():
    headers = {"Authorization": "Bearer sk_YOUR_API_KEY"}

    async with streamablehttp_client("https://mcp.postpost.dev", headers=headers) as (read, write, _):
        async with ClientSession(read, write) as session:
            await session.initialize()

            result = await session.call_tool("linkedin_account_stats", {
                "platformId": "linkedin-abc123",
                "aggregation": "TOTAL"
            })
            print(result.content[0].text)

linkedin_followers

Get follower count or growth over time.

Parameters:

ParameterTypeRequiredDescription
platformIdstringYesPlatform connection ID
periodstringNolifetime or daily
dateRangeobjectNoFor daily period. Structure: {start: {year, month, day}, end: {year, month, day}}

Example prompts:

"How many LinkedIn followers do I have?"
"Show my follower growth this month"
"What's my LinkedIn follower count?"
"Track my follower growth over the last 30 days"

Python example:

async def get_linkedin_followers():
    headers = {"Authorization": "Bearer sk_YOUR_API_KEY"}

    async with streamablehttp_client("https://mcp.postpost.dev", headers=headers) as (read, write, _):
        async with ClientSession(read, write) as session:
            await session.initialize()

            # Lifetime followers
            result = await session.call_tool("linkedin_followers", {
                "platformId": "linkedin-abc123",
                "period": "lifetime"
            })
            print(result.content[0].text)

            # Daily growth
            result = await session.call_tool("linkedin_followers", {
                "platformId": "linkedin-abc123",
                "period": "daily",
                "dateRange": {
                    "start": {"year": 2026, "month": 2, "day": 1},
                    "end": {"year": 2026, "month": 2, "day": 28}
                }
            })
            print(result.content[0].text)

linkedin_profile_summary

Get a combined profile overview with followers and stats.

Parameters:

ParameterTypeRequiredDescription
platformIdstringYesPlatform connection ID
dateRangeobjectNoDate range for stats. Structure: {start: {year, month, day}, end: {year, month, day}}

Example prompts:

"Give me a summary of my LinkedIn profile"
"How's my LinkedIn doing overall?"
"LinkedIn profile overview"

Python example:

async def get_linkedin_summary():
    headers = {"Authorization": "Bearer sk_YOUR_API_KEY"}

    async with streamablehttp_client("https://mcp.postpost.dev", headers=headers) as (read, write, _):
        async with ClientSession(read, write) as session:
            await session.initialize()

            result = await session.call_tool("linkedin_profile_summary", {
                "platformId": "linkedin-abc123"
            })
            print(result.content[0].text)

linkedin_create_reaction

React to a LinkedIn post.

Parameters:

ParameterTypeRequiredDescription
postedIdstringYesLinkedIn post URN
platformIdstringYesPlatform connection ID
reactionTypestringYesReaction type (see below)

Reaction types:

TypeDescription
LIKEStandard like
PRAISEClapping hands
EMPATHYHeart/love
INTERESTLightbulb/insightful
APPRECIATIONThank you
ENTERTAINMENTFunny/laughing

Example prompts:

"Like this LinkedIn post"
"React with PRAISE to post xyz"
"Add a heart reaction to my colleague's post"

Python example:

async def react_to_post():
    headers = {"Authorization": "Bearer sk_YOUR_API_KEY"}

    async with streamablehttp_client("https://mcp.postpost.dev", headers=headers) as (read, write, _):
        async with ClientSession(read, write) as session:
            await session.initialize()

            result = await session.call_tool("linkedin_create_reaction", {
                "postedId": "urn:li:share:7123456789",
                "platformId": "linkedin-abc123",
                "reactionType": "LIKE"
            })
            print(result.content[0].text)

linkedin_delete_reaction

Remove a reaction from a LinkedIn post.

Parameters:

ParameterTypeRequiredDescription
postedIdstringYesLinkedIn post URN
platformIdstringYesPlatform connection ID

Example prompts:

"Remove my reaction from this post"
"Unlike the LinkedIn post"

LinkedIn Comment Tools

linkedin_create_comment

Post a comment on a LinkedIn post.

Parameters:

ParameterTypeRequiredDescription
postedIdstringYesLinkedIn post URN (e.g., urn:li:share:123456 or urn:li:ugcPost:123456)
platformIdstringYesPlatform connection ID
messagestringYesComment text (max 1,250 characters)
parentCommentstringNoParent comment URN for nested replies

Example prompts:

"Comment 'Great insights!' on this LinkedIn post"
"Post a comment on my latest LinkedIn update"
"Reply to this comment with 'Thanks for sharing!'"

Python example:

async def comment_on_post():
    headers = {"Authorization": "Bearer sk_YOUR_API_KEY"}

    async with streamablehttp_client("https://mcp.postpost.dev", headers=headers) as (read, write, _):
        async with ClientSession(read, write) as session:
            await session.initialize()

            result = await session.call_tool("linkedin_create_comment", {
                "postedId": "urn:li:ugcPost:7429953213384187904",
                "platformId": "linkedin-abc123",
                "message": "Great insights! Thanks for sharing."
            })
            print(result.content[0].text)

Response example:

{
  "success": true,
  "comment": {
    "id": "7434695495614312448",
    "commentUrn": "urn:li:comment:(urn:li:ugcPost:xxx,7434695495614312448)",
    "message": "Great insights! Thanks for sharing."
  }
}

linkedin_delete_comment

Delete a comment from a LinkedIn post.

Parameters:

ParameterTypeRequiredDescription
postedIdstringYesLinkedIn post URN the comment belongs to
commentIdstringYesComment URN to delete
platformIdstringYesPlatform connection ID

Example prompts:

"Delete my comment from this post"
"Remove the comment I just posted"

Python example:

async def delete_comment():
    headers = {"Authorization": "Bearer sk_YOUR_API_KEY"}

    async with streamablehttp_client("https://mcp.postpost.dev", headers=headers) as (read, write, _):
        async with ClientSession(read, write) as session:
            await session.initialize()

            result = await session.call_tool("linkedin_delete_comment", {
                "postedId": "urn:li:ugcPost:7429953213384187904",
                "commentId": "urn:li:comment:(urn:li:ugcPost:xxx,7434695495614312448)",
                "platformId": "linkedin-abc123"
            })
            print(result.content[0].text)

LinkedIn Feed Retrieval Tools (Coming Soon — Requires LinkedIn Approval)

Status: DISABLED - These tools are not yet available. They require the r_member_social permission, which is RESTRICTED and requires LinkedIn approval. The implementation is ready and will be enabled once LinkedIn approves the permission for PostPost.

linkedin_posts

Retrieve posts authored by a LinkedIn account.

Parameters:

ParameterTypeRequiredDescription
platformIdstringYesPlatform connection ID (e.g., linkedin-XxxYyy)
startnumberNoStarting index for pagination (default: 0)
countnumberNoNumber of posts to retrieve (default: 10, max: 100)
sortBystringNoSort order: LAST_MODIFIED or CREATED (default: LAST_MODIFIED)

Example prompts:

"Show my recent LinkedIn posts"
"Get my last 10 LinkedIn posts"
"What have I posted on LinkedIn this month?"
"List my LinkedIn content"

Python example:

async def get_my_linkedin_posts():
    headers = {"Authorization": "Bearer sk_YOUR_API_KEY"}

    async with streamablehttp_client("https://mcp.postpost.dev", headers=headers) as (read, write, _):
        async with ClientSession(read, write) as session:
            await session.initialize()

            result = await session.call_tool("linkedin_posts", {
                "platformId": "linkedin-abc123",
                "count": 20,
                "sortBy": "LAST_MODIFIED"
            })
            print(result.content[0].text)

Response example:

{
  "success": true,
  "posts": [
    {
      "id": "urn:li:share:7123456789",
      "commentary": "Excited to share our latest product update!",
      "publishedAt": 1709294400000,
      "visibility": "PUBLIC",
      "lifecycleState": "PUBLISHED"
    }
  ],
  "pagination": {
    "start": 0,
    "count": 10,
    "total": 45
  },
  "cached": false
}

linkedin_post_comments

Retrieve comments on a specific LinkedIn post.

Parameters:

ParameterTypeRequiredDescription
postedIdstringYesLinkedIn post URN (e.g., urn:li:share:123456 or urn:li:ugcPost:123456)
platformIdstringYesPlatform connection ID
startnumberNoStarting index for pagination (default: 0)
countnumberNoNumber of comments to retrieve (default: 20, max: 100)

Example prompts:

"Show comments on my last LinkedIn post"
"Get all comments on this LinkedIn post"
"What are people saying about my post?"
"List comments on post urn:li:share:123456"

Python example:

async def get_post_comments():
    headers = {"Authorization": "Bearer sk_YOUR_API_KEY"}

    async with streamablehttp_client("https://mcp.postpost.dev", headers=headers) as (read, write, _):
        async with ClientSession(read, write) as session:
            await session.initialize()

            result = await session.call_tool("linkedin_post_comments", {
                "postedId": "urn:li:ugcPost:7429953213384187904",
                "platformId": "linkedin-abc123",
                "count": 50
            })
            print(result.content[0].text)

Response example:

{
  "success": true,
  "comments": [
    {
      "id": "6636062862760562688",
      "commentUrn": "urn:li:comment:(urn:li:activity:123,6636062862760562688)",
      "actor": "urn:li:person:xxx",
      "message": "Great insights! Thanks for sharing.",
      "created": { "time": 1582160678569 },
      "likesSummary": { "totalLikes": 5 },
      "commentsCount": 2
    }
  ],
  "pagination": {
    "start": 0,
    "count": 20,
    "total": 89
  },
  "cached": false
}

linkedin_post_reactions

Retrieve reactions on a specific LinkedIn post.

Parameters:

ParameterTypeRequiredDescription
postedIdstringYesLinkedIn post URN (e.g., urn:li:share:123456 or urn:li:ugcPost:123456)
platformIdstringYesPlatform connection ID
startnumberNoStarting index for pagination (default: 0)
countnumberNoNumber of reactions to retrieve (default: 50, max: 100)

Example prompts:

"Who liked my LinkedIn post?"
"Show reactions on this post"
"Get all reactions on my announcement"
"List people who reacted to my post"

Python example:

async def get_post_reactions():
    headers = {"Authorization": "Bearer sk_YOUR_API_KEY"}

    async with streamablehttp_client("https://mcp.postpost.dev", headers=headers) as (read, write, _):
        async with ClientSession(read, write) as session:
            await session.initialize()

            result = await session.call_tool("linkedin_post_reactions", {
                "postedId": "urn:li:ugcPost:7429953213384187904",
                "platformId": "linkedin-abc123",
                "count": 100
            })
            print(result.content[0].text)

Response example:

{
  "success": true,
  "reactions": [
    {
      "id": "urn:li:reaction:(urn:li:person:xxx,urn:li:activity:123)",
      "reactionType": "LIKE",
      "actor": "urn:li:person:xxx",
      "created": { "time": 1686183251857 }
    },
    {
      "id": "urn:li:reaction:(urn:li:person:yyy,urn:li:activity:123)",
      "reactionType": "PRAISE",
      "actor": "urn:li:person:yyy",
      "created": { "time": 1686183300000 }
    }
  ],
  "pagination": {
    "start": 0,
    "count": 50,
    "total": 456
  },
  "cached": false
}

Reaction types returned:

TypeDescription
LIKEStandard thumbs up
PRAISEClapping hands
EMPATHYHeart/love
INTERESTLightbulb (insightful)
APPRECIATIONThank you
ENTERTAINMENTFunny/laughing

Workspace Tools (B2B)

list_workspace_users

List team members in your workspace.

Parameters: None

Example prompts:

"Show my team members"
"Who's in my workspace?"
"List workspace users"

Python example:

async def list_workspace_users():
    headers = {"Authorization": "Bearer sk_YOUR_API_KEY"}

    async with streamablehttp_client("https://mcp.postpost.dev", headers=headers) as (read, write, _):
        async with ClientSession(read, write) as session:
            await session.initialize()

            result = await session.call_tool("list_workspace_users", {})
            print(result.content[0].text)

create_workspace_user

Add a new user to your workspace.

Parameters:

ParameterTypeRequiredDescription
usernamestringYesEmail address
displayNamestringNoDisplay name for the user

Example prompts:

"Add john@example.com to my workspace"
"Create a new team member"
"Invite marketing@company.com to join"

Python example:

async def add_workspace_user():
    headers = {"Authorization": "Bearer sk_YOUR_API_KEY"}

    async with streamablehttp_client("https://mcp.postpost.dev", headers=headers) as (read, write, _):
        async with ClientSession(read, write) as session:
            await session.initialize()

            result = await session.call_tool("create_workspace_user", {
                "username": "newuser@company.com",
                "displayName": "New User"
            })
            print(result.content[0].text)

workspace_detach_user

Remove a user from your workspace.

Parameters:

ParameterTypeRequiredDescription
userIdstringYesUser ID to remove

Example prompts:

"Remove user xyz from my workspace"
"Detach this team member"

Error Handling

When a tool encounters an error, it throws an exception that the MCP client will receive. Common error messages include:

Error MessageCause
"API key required..."Missing or invalid API key
"Platform ID not found"Invalid platform connection ID
"Post not found"Invalid post group ID
"API error: 429"Rate limited by the API
"API error: 502"Platform API temporarily unavailable

Example error handling in Python:

try:
    result = await session.call_tool("create_post", {
        "content": "Hello world!",
        "platforms": ["linkedin-abc123"],
        "scheduledTime": "2026-03-01T14:00:00Z"
    })
    print(result.content[0].text)
except Exception as e:
    print(f"Tool error: {e}")

Best Practices

  1. Always get connections first — Use list_connections to get valid platform IDs before creating posts

  2. Use ISO 8601 dates — All dates should be in format 2026-03-01T14:00:00Z

  3. Respect character limits — Check platform limits before creating posts

  4. Handle errors gracefully — Check for error responses in tool results

  5. Batch operations — When posting to multiple platforms, include all platform IDs in a single create_post call

On this page