mcpField
C
Content Distribution Mcp

Content Distribution Mcp

Local
automatelab.techSocial Media4Updated 2d ago

About Content Distribution Mcp

Content Distribution Mcp distributes one piece of content across social and publishing channels, adapting variants for platform constraints and tracking publication state. It is for agents and teams that need repeatable publishing, with idempotent retries, scheduling, and browser handoffs for some channels.

Key features

  1. 01Publish to eight listed channels
  2. 02Provide per-channel formatting hints
  3. 03Schedule and drain queued posts
  4. 04Track channel-specific post status
  5. 05Retry publishes idempotently
  6. 06Return browser compose links for some channels

Use cases

  1. 01Distribute a product announcement across channels
  2. 02Schedule posts for later publication
  3. 03Check whether a channel publish succeeded

MCP support

Exposes eight MCP tools for publishing, scheduling, status checks, channel hints, profiles, and subreddit data. MCP clients connect to the server over stdio; LinkedIn, Medium, and X/Twitter use browser compose fallbacks.

Configuration

Local server config is the same for every client. Copy it into your client’s MCP config file.

mcp.json · Universal config
{
"mcpServers": {
"content-distribution-mcp-automatelab-tech": {
"command": "npx",
"args": [
"-y",
"@automatelab/content-distribution-mcp"
],
"env": {
"DEV_TO_API_KEY": "<DEV_TO_API_KEY>",
"HASHNODE_TOKEN": "<HASHNODE_TOKEN>",
"HASHNODE_PUBLICATION_ID": "<HASHNODE_PUBLICATION_ID>",
"GITHUB_TOKEN": "<GITHUB_TOKEN>",
"GITHUB_DISCUSSION_REPO": "<GITHUB_DISCUSSION_REPO>",
"REDDIT_CLIENT_ID": "<REDDIT_CLIENT_ID>",
"REDDIT_CLIENT_SECRET": "<REDDIT_CLIENT_SECRET>",
"REDDIT_USERNAME": "<REDDIT_USERNAME>",
"REDDIT_PASSWORD": "<REDDIT_PASSWORD>",
"BLUESKY_IDENTIFIER": "<BLUESKY_IDENTIFIER>",
"BLUESKY_PASSWORD": "<BLUESKY_PASSWORD>",
"DISTRIBUTION_BACKEND": "<DISTRIBUTION_BACKEND>",
"DISTRIBUTION_BACKEND_DIR": "<DISTRIBUTION_BACKEND_DIR>"
}
}
}
}
Run commandnpx -y @automatelab/content-distribution-mcp
Environment variables to set
DEV_TO_API_KEYSecretDEV.to API key for publishing articles
HASHNODE_TOKENSecretHashnode personal access token
HASHNODE_PUBLICATION_IDHashnode publication ID
GITHUB_TOKENSecretGitHub personal access token for GitHub Discussions
GITHUB_DISCUSSION_REPOGitHub repo for Discussions in owner/repo format
REDDIT_CLIENT_IDSecretReddit OAuth app client ID
REDDIT_CLIENT_SECRETSecretReddit OAuth app client secret
REDDIT_USERNAMEReddit account username
REDDIT_PASSWORDSecretReddit account password
BLUESKY_IDENTIFIERBluesky handle (e.g. you.bsky.social)
BLUESKY_PASSWORDSecretBluesky app password
DISTRIBUTION_BACKENDState backend (default: yaml)
DISTRIBUTION_BACKEND_DIRDirectory for YAML state files (default: ~/.distribution-mcp)

Local servers need a runtime on your machine (e.g. Node.js 18+). Config file locations differ by client; see your client’s docs.

Packages
npm@automatelab/content-distribution-mcp2.2.1

Tools

8

Saved tool list · updated 3w ago

ParameterTypeRequiredDescription
contentobjectYes
content.idstringYesStable identifier, e.g. 'my-post@2026-05-20'. Used as the idempotency key together with channel; must be unique per content piece.
content.tagsarrayNoCanonical tag list; each channel adapter normalizes, truncates, or converts to platform tag syntax.
content.titlestringYesTitle of the content piece; used as the post title on most channels.
content.authorstringYesAuthor display name; used in author metadata on channels that accept it.
content.body_mdstringYesFull body in Markdown. Each channel adapter converts or truncates to platform requirements.
content.subtitlestringNoOptional subtitle; used on Hashnode and DEV.to subtitle fields; ignored by channels that do not support subtitles.
content.cta_blockstringNoOptional call-to-action block appended to the post body on channels that support it; formatted as Markdown.
content.cover_imagestringNoOptional URL of a cover image; used as the header image on Hashnode and DEV.to; omit if no image is available.
content.canonical_urlstringNoCanonical URL of the authoritative source; set as canonical_url on DEV.to and Hashnode to signal the original for SEO; omit when publishing first to that channel.
content.source_task_idstringNoOptional tracing ID (e.g. Notion task ID); stored in publish state for correlation but never sent to platforms.
variantsarrayYes
profile_namestringYesName of the distribution profile (credentials store). Use profile.list to discover available names.

Details

From the project README

content-distribution-mcp

Publish your content everywhere—without rewriting for every platform.

A MCP server that distributes a single piece of content across 8+ channels (DEV.to, Hashnode, GitHub Discussions, Reddit, Bluesky, LinkedIn, Medium, Twitter) with automatic platform-specific adaptation, idempotent publishing, per-community anti-spam rules, and centralized state management.

The Problem It Solves

Creating and publishing content at scale is friction-heavy:

  • Different formats: Reddit strips formatting, Twitter has character limits, DEV.to supports embeds and rich media. Each needs customized copy.
  • Platform rules: Subreddits enforce cooldowns and flair requirements. Communities have posting patterns and automoderator gates. LinkedIn suppresses external links.
  • State chaos: Which posts went live where? What if a publish fails halfway? Did that Reddit post get auto-removed by spam filters?

This MCP handles distribution complexity. Write your core message once, generate platform-specific variants, publish everywhere safely.

How It Works

  1. Your agent generates channel-specific copy variants (rewritten titles, trimmed text, platform-appropriate tags, audience-matched tone).
  2. This MCP publishes each variant with idempotency, OAuth, API retries, and scheduling—enforcing platform constraints automatically.
  3. You control which platforms get what. The MCP returns per-channel hints (character limits, tag vocabularies, cooldowns) but leaves creative decisions to you.

No LLM calls inside. No walled-in agents. Just a clean API for multi-platform content distribution at scale.

Install

npx -y @automatelab/content-distribution-mcp

Or add it permanently to your MCP host.

Wire into your MCP host

Claude Code — add to .claude/mcp.json:

{
  "mcpServers": {
    "content-distribution": {
      "command": "npx",
      "args": ["-y", "@automatelab/content-distribution-mcp"]
    }
  }
}

Claude Desktop — add to claude_desktop_config.json:

{
  "mcpServers": {
    "content-distribution": {
      "command": "npx",
      "args": ["-y", "@automatelab/content-distribution-mcp"]
    }
  }
}

n8n — use the MCP Client node, point it at npx -y @automatelab/content-distribution-mcp over stdio.

Cursor / Windsurf / any MCP host — same npx -y @automatelab/content-distribution-mcp pattern.

Configure credentials

The server reads credentials from a Distribution Profile stored in ~/.distribution-mcp/profiles.yaml:

# ~/.distribution-mcp/profiles.yaml
default:
  credentials:
    DEV_TO_API_KEY: "your-devto-api-key"
    HASHNODE_TOKEN: "your-hashnode-token"
    HASHNODE_PUBLICATION_ID: "your-pub-id"
    GITHUB_TOKEN: "ghp_..."
    GITHUB_DISCUSSION_REPO: "owner/repo"
    REDDIT_CLIENT_ID: "..."
    REDDIT_CLIENT_SECRET: "..."
    REDDIT_USERNAME: "..."
    REDDIT_PASSWORD: "..."
    BLUESKY_IDENTIFIER: "you.bsky.social"
    BLUESKY_PASSWORD: "..."
  subreddits:
    - ClaudeAI
    - LocalLLaMA

Only set credentials for channels you intend to use. LinkedIn, Medium, and Twitter/X return needs_browser with a compose URL — no credentials needed.

MCP tool surface

Eight tools, dot-notation names form a navigable tree (post.*, channel.*, profile.*, subreddit.*). Every tool declares an outputSchema (callers can type-check responses) and MCP annotations (read-only / destructive / idempotent / open-world hints). No LLM calls inside the server.

ToolPurpose
post_publishImmediate publish; idempotent on (content.id, channel)
post_scheduleQueue variants for schedule_at, publish the rest immediately
post_drainFire all scheduled posts due now — run from cron
post_statusPer-channel state for a content piece or channel
post_unpublishBest-effort delete (DEV.to sets unpublished; others vary)
channel_hintsPer-channel metadata: char limits, Markdown support, tag vocab
profile_listNames of configured distribution profiles
subreddit_listSubreddit Catalog: cooldowns, flair vocab, last-posted

v2.2.0 breaking change. Tools were renamed from flat names (publish, schedule, ...) to dot-notation (post_publish, post_schedule, ...). Update any prompts, agent skills, or n8n nodes that referenced the old names.

Channels

Channel keyTierAuth
devtoAutoDEV_TO_API_KEY
hashnodeAutoHASHNODE_TOKEN + HASHNODE_PUBLICATION_ID
github_discussionsAutoGITHUB_TOKEN + GITHUB_DISCUSSION_REPO
redditAuto-gatedREDDIT_CLIENT_ID/SECRET/USERNAME/PASSWORD
blueskyAutoBLUESKY_IDENTIFIER + BLUESKY_PASSWORD
linkedinBrowser fallbackreturns needs_browser + compose URL
mediumBrowser fallbackreturns needs_browser + compose URL
twitter / xBrowser fallbackreturns needs_browser + compose URL

Example agent call

// post_publish tool
{
  "content": {
    "id": "n8n-webhook-setup@2026-05-20",
    "title": "How to set up an n8n webhook",
    "body_md": "...",
    "tags": ["automation", "n8n", "tutorial"],
    "canonical_url": "https://yourblog.com/n8n-webhook-setup",
    "author": "You"
  },
  "variants": [
    {
      "channel": "devto:main",
      "title": "How to set up an n8n webhook",
      "body": "...",
      "tags": ["automation", "n8n", "tutorial", "devops"],
      "canonical_url": "https://yourblog.com/n8n-webhook-setup",
      "extras": {}
    },
    {
      "channel": "reddit:ClaudeAI",
      "title": "Built a webhook automation with n8n",
      "body": "Here's how I set it up...",
      "tags": [],
      "extras": { "flair": "Project" }
    }
  ],
  "profile_name": "default"
}

Idempotency

Re-running post_publish with the same content.id + channel pair returns the existing live_url immediately without making another platform API call. Safe to retry on failure.

Scheduling

Variants with schedule_at (ISO-8601 with timezone, e.g. "2026-05-21T09:00:00+00:00") are stored in ~/.distribution-mcp/scheduled.yaml and fired on the next post_drain call. Run drain from cron:

# fire due posts every 5 minutes
*/5 * * * * npx -y @automatelab/content-distribution-mcp drain

Or call the post_drain MCP tool directly from an agent.

Environment variables

VariableDefaultPurpose
DISTRIBUTION_BACKENDyamlState backend (yaml only in v1)
DISTRIBUTION_BACKEND_DIR~/.distribution-mcpDirectory for YAML state files

Requirements

  • Node.js 18 or later

Architecture

Agent (Claude Code / n8n / Cursor / any MCP host)
  │  generates per-channel copy, calls MCP tools
  ▼
content-distribution-mcp  (this package, stdio transport)
  │  no LLM calls — pure I/O
  ├── adapters/   devto · hashnode · github-discussions · reddit · bluesky · browser
  └── backends/   yaml (post log · profiles · schedule queue · subreddit catalog)

Works with any MCP client

No Anthropic-specific code anywhere. Verify:

grep -ri "anthropic" node_modules/content-distribution-mcp/dist/  # returns nothing

Part of the AutomateLab stack

License

MIT

Maintenance and verification

See the maintenance guide for interpretation limits, current tool names where applicable, and reproducible verification.

Comments

Markdown supported

New to MCP?

From what the protocol is to installing your first server, these answers cover most first questions.

An open protocol that defines how AI applications connect to external tools and data in a uniform way. Clients talk to the model; MCP servers provide tools, resources and prompt templates. They exchange standard messages, so one server can be reused by many clients.