MCP Integration
Tool Reference

MCP Tool Reference

All 21 tools exposed by the Pharlo MCP server, organized by domain. The machine-readable equivalent of this page is /mcp-tools.json (opens in a new tab). For end-to-end recipes that chain these tools, see the Agent Workflows; for safe usage rules, see Agent Rules.

Annotations key

AnnotationMeaning
readOnlyDoes not mutate data — safe to call freely
destructiveHard or impossible to undo — Claude will ask for confirmation
idempotentCalling multiple times produces the same result
openWorldMakes calls to an external platform (YouTube, Facebook)

Assignments

Assignments are publishing jobs. Each one moves through a lifecycle: pendinguploadinguploadedprocessingpublished (or failed / cancelled).

See Workflows for end-to-end prompt patterns, and Assignments REST reference for the underlying API.


create_assignment

Create a new publishing job to post content to a social media platform.

readOnly: false | destructive: true | idempotent: false | openWorld: true

⚠️

YouTube default privacy is "private". Always set "privacy": "public" explicitly in your prompt or payload if you want the video publicly visible.

Call get_platform_capabilities before this tool to discover supported payload fields, character limits, and allowed values for the target platform.

Three ways to supply media — pick exactly one. mediaUrl for an already-public direct media URL, fileContent for small base64-encoded chat attachments, or uploadSessionId for large local files uploaded through the browser. For the large-file flow, start with create_assignment_upload_session and only call this tool once the session status is completed.

ParameterTypeRequiredDescription
connectionIdUUIDYesThe channel to publish to — get it from list_connections
typestringYesvideo, image, link, text, reel, short, story, carousel
payloadJSON stringYesPlatform-specific fields (title, description, privacy, tags, etc.)
scheduledAtISO 8601NoScheduled publish time — must include timezone offset e.g. +03:00
mediaUrlURLNoPublicly accessible media URL (one of three media sources)
fileContentbase64 stringNoBase64-encoded small chat attachment (one of three media sources)
uploadSessionIdUUIDNoCompleted create_assignment_upload_session ID for large local files (one of three media sources)
callbackUrlURLNoWebhook URL called on every status change — see Webhooks guide
idempotencyKeystringNoUnique string to prevent duplicate submissions on retry
mediaContentTypestringNoMIME type of the media file, e.g. video/mp4
mediaSizeBytesintNoMedia file size in bytes — used for upload progress tracking

Example prompts:

"Upload https://cdn.example.com/demo.mp4 (opens in a new tab) to my YouTube channel 'Tech Reviews'. Title: 'Product Demo v3', make it public, schedule for Friday at 6 PM Berlin time."

"Post this video to my Facebook page as public. Description: 'Check out our new feature'. Use https://cdn.example.com/promo.mp4 (opens in a new tab)"

Example payload — YouTube video:

{
  "connectionId": "7f3e1a2b-4c5d-6e7f-8a9b-0c1d2e3f4a5b",
  "type": "video",
  "mediaUrl": "https://cdn.example.com/demo.mp4",
  "mediaContentType": "video/mp4",
  "scheduledAt": "2026-04-25T18:00:00+02:00",
  "payload": "{\"title\":\"Product Demo v3\",\"description\":\"See what's new\",\"privacy\":\"public\",\"tags\":[\"demo\",\"product\"]}"
}

Example payload — Facebook post:

{
  "connectionId": "9a8b7c6d-5e4f-3210-fedc-ba9876543210",
  "type": "video",
  "mediaUrl": "https://cdn.example.com/promo.mp4",
  "payload": "{\"description\":\"Check out our new feature!\",\"privacy\":\"EVERYONE\"}"
}

Programmatic usage (custom agents):

import anthropic
 
client = anthropic.Anthropic()
 
response = client.beta.messages.create(
    model="claude-opus-4-7",
    max_tokens=1024,
    betas=["mcp-client-2025-04-04"],
    mcp_servers=[
        {
            "type": "url",
            "url": "https://pharlo.io/_mcp",
            "authorization_token": "mcp_at_your_token",
        }
    ],
    messages=[
        {
            "role": "user",
            "content": (
                "Upload https://cdn.example.com/demo.mp4 to my YouTube channel "
                "'Tech Reviews'. Title: 'Product Demo v3', public, "
                "schedule for 2026-04-25T18:00:00+02:00."
            ),
        }
    ],
)
 
for block in response.content:
    if hasattr(block, "text"):
        print(block.text)

create_assignment_upload_session

Create a browser upload session for a large local media file that will later be published as an assignment.

readOnly: false | destructive: false | idempotent: false | openWorld: true

Large-file workflow. Use this when the user wants to upload a local video (e.g. to YouTube from their computer) instead of supplying a public mediaUrl. Call it with connectionId only — do not ask for or invent file name, MIME type, or size; the browser upload page reads that metadata from the selected file. Give the returned uploadPageUrl to the user, then poll with get_assignment_upload_session.

ParameterTypeRequiredDescription
connectionIdUUIDYesThe channel the uploaded file will publish to
fileNamestringNoOptional — normally detected by the browser upload page
fileMimeTypestringNoOptional — normally detected by the browser upload page
fileSizeBytesintNoOptional — normally detected by the browser upload page

Response includes: sessionId, uploadPageUrl, status, expiresAt

Example prompts:

"I want to upload a video from my computer to my 'Tech Reviews' YouTube channel."

"Give me an upload link for a large local file."


get_assignment_upload_session

Get the current status of a browser upload session created by create_assignment_upload_session.

readOnly: true | destructive: false | idempotent: true | openWorld: false

Poll this after the user opens uploadPageUrl. When status is completed, call create_assignment with the same session ID as uploadSessionId. If status is expired, cancelled, or consumed, create a new session instead.

ParameterTypeRequiredDescription
sessionIdUUIDYesThe upload session ID returned by create_assignment_upload_session

Example prompt:

"Is my upload finished yet?"


list_assignments

List publishing assignments with optional filters and pagination.

readOnly: true | destructive: false | idempotent: true | openWorld: false

ParameterTypeRequiredDescription
pageintNoPage number (default: 1)
limitintNoItems per page (default: 10, max: 50)
statusstringNopending, uploading, uploaded, processing, published, failed, cancelled
platformstringNoyoutube, facebook
connectionIdUUIDNoFilter by channel
externalIdstringNoFilter by your custom ID
dateFromISO 8601NoCreated after this date
dateToISO 8601NoCreated before this date
compactboolNoReturn compact items (default: true)

Example prompts:

"Show me my last 10 assignments."

"List all failed assignments from the past week on my YouTube channel."

"What assignments are currently pending or processing?"


get_assignment

Get full details of a specific assignment including status, errors, platform URL, and payload.

readOnly: true | destructive: false | idempotent: true | openWorld: false

ParameterTypeRequiredDescription
assignmentIdUUIDYesAssignment UUID

Example prompt:

"What's the status of assignment a1b2c3d4-e5f6-7890-abcd-ef1234567890? Did it publish?"

Example response fields:

{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "status": "published",
  "platform": "youtube",
  "type": "video",
  "platformUrl": "https://youtu.be/dQw4w9WgXcQ",
  "publishedAt": "2026-04-25T16:02:00Z",
  "scheduledAt": "2026-04-25T16:00:00Z",
  "payload": { "title": "Product Demo v3", "privacy": "public" }
}

update_assignment

Update a pending or uploaded assignment's scheduled time or payload before it is published.

readOnly: false | destructive: true | idempotent: false | openWorld: false

⚠️

This tool only works on assignments that have not yet been published. To edit a post that is already live, use update_published_content instead — it pushes the change to the platform directly.

ParameterTypeRequiredDescription
assignmentIdUUIDYesAssignment UUID
scheduledAtISO 8601NoNew scheduled time (with timezone offset)
payloadJSON stringNoNew content payload

Example prompts:

"Reschedule assignment a1b2c3d4 to Monday at 9 AM Kyiv time."

"Change the title of my pending assignment a1b2c3d4 to 'Q2 Launch'."


update_published_content

Update the metadata of an already published assignment directly on the platform.

readOnly: false | destructive: false | idempotent: true | openWorld: true

Currently supported for YouTube only. Changes (title, description, tags, privacy) are applied to the platform in real time. For not-yet-published assignments use update_assignment. If the connection token is expired, re-authorize via get_oauth_connect_url first.

ParameterTypeRequiredDescription
assignmentIdUUIDYesAssignment UUID of the published post
titlestringNoNew video title (max 100 chars)
descriptionstringNoNew video description (max 5000 chars)
tagsJSON stringNoTags as a JSON array string, e.g. ["tag1","tag2"] (max 500 chars total)
privacystringNopublic, unlisted, or private

Example prompts:

"Change the title of my published video a1b2c3d4 to 'Q2 Launch — Updated'."

"Make my published YouTube video a1b2c3d4 unlisted."


retry_assignment

Retry a failed assignment. Re-queues it without creating a new assignment.

readOnly: false | destructive: false | idempotent: true | openWorld: true

ParameterTypeRequiredDescription
assignmentIdUUIDYesUUID of a failed assignment

Example prompt:

"Retry my failed assignment a1b2c3d4."

"List all failed assignments from today and retry them."


cancel_assignment

Cancel a pending or scheduled assignment.

readOnly: false | destructive: true | idempotent: false | openWorld: false

⚠️

Cancelled assignments cannot be restarted. Use update_assignment to reschedule instead of cancelling and recreating.

ParameterTypeRequiredDescription
assignmentIdUUIDYesAssignment UUID

Example prompt:

"Cancel assignment a1b2c3d4 — I need to update the video first."


Connections

A connection represents an authorized social media channel (YouTube channel, Facebook page). You need a connectionId before you can create assignments.

See Connections REST reference for the underlying API.


list_connections

List all authorized channels.

readOnly: true | destructive: false | idempotent: true | openWorld: false

ParameterTypeRequiredDescription
pageintNoPage number (default: 1)
limitintNoItems per page (default: 10, max: 50)
platformstringNoyoutube, facebook
includeInactiveboolNoInclude deactivated connections (default: false)

Example prompts:

"List all my connected YouTube channels."

"Show me all my social media connections including inactive ones."


get_connection

Get details for a specific connection: token status, channel metadata, and configuration.

readOnly: true | destructive: false | idempotent: true | openWorld: false

If tokenStatus is expired, use get_oauth_connect_url with connectionId to re-authorize that specific channel without losing it.

ParameterTypeRequiredDescription
connectionIdUUIDYesConnection UUID

Example prompt:

"Show me the details and token status of my 'Tech Reviews' YouTube channel."


update_connection

Update a connection's display name or active status.

readOnly: false | destructive: false | idempotent: true | openWorld: false

ParameterTypeRequiredDescription
connectionIdUUIDYesConnection UUID
namestringNoNew display name
isActiveboolNotrue to activate, false to deactivate

Example prompts:

"Rename my YouTube connection a1b2c3d4 to 'Main Channel'."

"Deactivate the Facebook page connection 9a8b7c6d — we're pausing that account."


Analytics

Live analytics tools that query the platform API in real time (YouTube Data API, Meta Graph API). Each call counts against both your Pharlo bill and the platform's own quota.

See Analytics REST reference for the underlying API.


get_channel_stats

Live channel-level metrics for a connection: subscribers, total views, total posts.

readOnly: true | destructive: false | idempotent: true | openWorld: true

ParameterTypeRequiredDescription
connectionIdUUIDYesConnection UUID

Example prompts:

"How many subscribers does my 'Tech Reviews' channel have right now?"

"Show me the current view count and post count for all my YouTube channels."


get_post_stats

Live performance metrics for a single published post: views, likes, comments, shares.

readOnly: true | destructive: false | idempotent: true | openWorld: true

ParameterTypeRequiredDescription
connectionIdUUIDYesConnection UUID the post belongs to
postIdUUIDYesAssignment UUID of the published post

Example prompts:

"How is my latest video performing?"

"Get the current view and like count for post a1b2c3d4 on my 'Tech Reviews' channel."


get_connection_stats

Current follower/subscriber/view counts for a single connection, served from the latest cached snapshot.

readOnly: true | destructive: false | idempotent: true | openWorld: true

Unlike get_channel_stats, this returns the latest cached snapshot. If the platform API is unavailable, it still returns the last cached values with a note about cache age.

ParameterTypeRequiredDescription
connectionIdUUIDYesConnection UUID

Example prompt:

"What's the latest subscriber count for my 'Tech Reviews' channel?"


get_stats

Unified analytics tool. Select a report with the report parameter; aggregated reports are read from Pharlo's own analytics store (no live platform call).

readOnly: true | destructive: false | idempotent: true | openWorld: false

ReportDescription
overviewHigh-level totals: channels, posts, success rate
dashboardDaily/weekly aggregates, top posts, growth
analyticsEngagement trends, totals, top posts (80 KB truncation guard)
recent_postsLatest published posts with stats (use limit, max 50)
subscriber_growthFollower/subscriber growth time series
publishing_patternPost frequency by hour-of-day and day-of-week
compareSide-by-side stats for two connections (requires connectionId + compareConnectionId, must differ)
ParameterTypeRequiredDescription
reportstringYesOne of the report types above
platformstringNoyoutube, facebook
connectionIdUUIDNoLimit to a single connection
dateFromISO 8601NoStart of the date range
dateToISO 8601NoEnd of the date range
daysintNoTrailing window in days
metricstringNoanalytics report: which metric to trend
contentTypestringNoanalytics report: filter by content type
limitintNorecent_posts report: number of posts (max 50)
compareConnectionIdUUIDNocompare report: the second connection

Example prompts:

"Give me an overview of all my channels this month."

"Show me my subscriber growth over the last 90 days."

"Compare my two YouTube channels side by side."


OAuth

Authorize a new social channel (YouTube or Meta) for publishing.

See OAuth REST reference for the underlying API.


get_oauth_connect_url

Generate an OAuth consent URL to connect a new channel or re-authorize an existing one.

readOnly: false | destructive: false | idempotent: false | openWorld: true

Two-step flow: call this tool → user opens the returned URL in a browser and completes OAuth → call list_connections to verify the new channel appears (ticket lifetime: 10 minutes).

ParameterTypeRequiredDescription
platformstringYesyoutube or facebook
connectionIdUUIDNoExisting connection UUID to re-authorize (omit when connecting a new channel)
organizationIdUUIDNoOrganization to associate the new connection with

Response includes: url, ticketId, expiresIn, platform, instructions

Example prompts:

"I want to connect my second YouTube channel to Pharlo."

"My YouTube token has expired — re-authorize my 'Tech Reviews' channel."


check_oauth_status

Check whether a recent OAuth connection attempt (started with get_oauth_connect_url) has completed.

readOnly: true | destructive: false | idempotent: true | openWorld: false

Use the ticketId returned by get_oauth_connect_url to poll the flow: pending (user has not finished in the browser yet), success (with connection details), failed (with error details), or expired.

ParameterTypeRequiredDescription
ticketIdstringYesOAuth ticket ID returned by get_oauth_connect_url

Example prompt:

"Did my YouTube connection go through?"


Platforms

Platform capabilities describe what each social network supports: content types, payload fields, character limits, allowed values, and file size constraints. Always check capabilities before creating assignments.

See Platform Capabilities REST reference for the underlying API.


list_platforms

List all supported platforms with slugs, display names, and supported content types.

readOnly: true | destructive: false | idempotent: true | openWorld: false

No parameters.

Example prompt:

"What platforms does Pharlo support?"

Example response:

[
  { "slug": "youtube", "name": "YouTube", "hasCapabilities": true, "contentTypes": ["video", "short"] },
  { "slug": "facebook", "name": "Facebook", "hasCapabilities": true, "contentTypes": ["video", "image", "link", "text", "reel", "story"] }
]

get_platform_capabilities

Get detailed capabilities for a platform: content types, file size limits, payload fields with types, defaults, and constraints.

readOnly: true | destructive: false | idempotent: true | openWorld: false

Always call this before create_assignment. Platform capabilities tell you exactly which payload fields are available, their types, maximum lengths, and default values — so Claude can build a valid payload without guessing.

ParameterTypeRequiredDescription
platformstringYesyoutube or facebook

Example prompt:

"What payload fields does YouTube support for video assignments?"

Example response (abbreviated):

{
  "platform": "youtube",
  "contentTypes": {
    "video": {
      "payloadSchema": {
        "title":       { "type": "string", "required": true, "maxLength": 100 },
        "description": { "type": "string", "maxLength": 5000 },
        "privacy":     { "type": "enum", "values": ["public", "unlisted", "private"], "default": "private" },
        "tags":        { "type": "array", "items": "string", "maxItems": 500 }
      },
      "mediaConstraints": {
        "maxSizeBytes": 137438953472,
        "allowedMimeTypes": ["video/mp4", "video/quicktime", "video/x-msvideo"]
      }
    }
  }
}

Webhooks

Webhooks deliver real-time status change notifications to your server. See Webhooks guide and Webhooks REST reference for setup details.


list_webhook_deliveries

List recent webhook delivery attempts with HTTP response codes and error details.

readOnly: true | destructive: false | idempotent: true | openWorld: false

ParameterTypeRequiredDescription
statusstringNopending, delivered, failed
pageintNoPage number (default: 1)
limitintNoItems per page (default: 10, max: 50)

Example prompts:

"Show me recent webhook delivery failures."

"Were all webhooks delivered successfully today?"