{"_id":"@automatelab/content-distribution-mcp","_rev":"7-459388919e5028e2d3ea54af6cd421ea","name":"@automatelab/content-distribution-mcp","dist-tags":{"latest":"3.0.0"},"versions":{"2.0.1":{"name":"@automatelab/content-distribution-mcp","version":"2.0.1","keywords":["mcp","content-distribution","devto","hashnode","reddit","bluesky","linkedin","twitter","medium","github-discussions","automation","model-context-protocol"],"author":{"name":"automatelab"},"license":"MIT","_id":"@automatelab/content-distribution-mcp@2.0.1","maintainers":[{"name":"ratamaha","email":"hello@automatelab.tech"}],"homepage":"https://automatelab.tech/products/mcp/content-distribution-mcp/","bugs":{"url":"https://github.com/AutomateLab-tech/content-distribution-mcp/issues"},"bin":{"cdmcp":"dist/index.js","content-distribution-mcp":"dist/index.js"},"dist":{"shasum":"10236f458a19e52688757c79fd440682434e8223","tarball":"https://registry.npmjs.org/@automatelab/content-distribution-mcp/-/content-distribution-mcp-2.0.1.tgz","fileCount":59,"integrity":"sha512-v2t3pT96PyEXakhjR2ElVcNUj6imOCw14lXL7f54sOAV7UUKw3Xyk2Lrv7wY8NwWI0ciNHYM/F4iNx2OFdIjAg==","signatures":[{"sig":"MEYCIQC7iwk93b3k8VDkWBEUKVKYZeMkOnjwLmnMARCx2+H17AIhAPDPTnz4f4pylfvilxpnENAqt/+B93pF+ENTwqi1BIVG","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":88084},"main":"dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"gitHead":"fda1539671cf752a752aa388b38c52ed7c2bb958","scripts":{"build":"tsc","prepare":"npm run build"},"_npmUser":{"name":"ratamaha","email":"hello@automatelab.tech"},"repository":{"url":"git+https://github.com/AutomateLab-tech/content-distribution-mcp.git","type":"git"},"_npmVersion":"11.12.1","description":"Multi-channel content distribution MCP server. Publish one piece of content to DEV.to, Hashnode, GitHub Discussions, Reddit, Bluesky, LinkedIn, Medium, and Twitter with idempotent state.","directories":{},"_nodeVersion":"24.15.0","dependencies":{"zod":"^3.23.0","js-yaml":"^4.1.0","@modelcontextprotocol/sdk":"^1.12.0"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.4.0","@types/node":"^20.0.0","@types/js-yaml":"^4.0.9"},"_npmOperationalInternal":{"tmp":"tmp/content-distribution-mcp_2.0.1_1779285965169_0.9411914590499315","host":"s3://npm-registry-packages-npm-production"}},"2.1.0":{"name":"@automatelab/content-distribution-mcp","version":"2.1.0","keywords":["mcp","content-distribution","devto","hashnode","reddit","bluesky","linkedin","twitter","medium","github-discussions","automation","model-context-protocol"],"author":{"name":"automatelab"},"license":"MIT","_id":"@automatelab/content-distribution-mcp@2.1.0","maintainers":[{"name":"ratamaha","email":"hello@automatelab.tech"}],"homepage":"https://automatelab.tech/products/mcp/content-distribution-mcp/","bugs":{"url":"https://github.com/AutomateLab-tech/content-distribution-mcp/issues"},"bin":{"cdmcp":"dist/index.js","content-distribution-mcp":"dist/index.js"},"dist":{"shasum":"95cd7d8c2eebfc628e39c5c3fc08c05894ec3754","tarball":"https://registry.npmjs.org/@automatelab/content-distribution-mcp/-/content-distribution-mcp-2.1.0.tgz","fileCount":59,"integrity":"sha512-dSetrj2Uo/7fHHxlbbzA9dKtDpRZl/1Fh3Il9E8X9VQLG+mAs64TRKt90BXYUURBo/Y6A6+PPqiPBHN9N84sZg==","signatures":[{"sig":"MEYCIQC/KvEmTBfQjFDjjk19slccVQ273tmoOXVBifRov34F/QIhAKfhs5XD8Il4gPRRCxvOiK8fnya52ez0vxTlljWS2CeV","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":88084},"main":"dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"gitHead":"124a8b85e4af8fd368cff177bbf916e92215e137","scripts":{"build":"tsc","prepare":"npm run build"},"_npmUser":{"name":"ratamaha","email":"hello@automatelab.tech"},"repository":{"url":"git+https://github.com/AutomateLab-tech/content-distribution-mcp.git","type":"git"},"_npmVersion":"11.12.1","description":"Multi-channel content distribution MCP server. Publish one piece of content to DEV.to, Hashnode, GitHub Discussions, Reddit, Bluesky, LinkedIn, Medium, and Twitter with idempotent state.","directories":{},"_nodeVersion":"24.15.0","dependencies":{"zod":"^3.23.0","js-yaml":"^4.1.0","@modelcontextprotocol/sdk":"^1.12.0"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.4.0","@types/node":"^20.0.0","@types/js-yaml":"^4.0.9"},"_npmOperationalInternal":{"tmp":"tmp/content-distribution-mcp_2.1.0_1779290466907_0.43363789128070396","host":"s3://npm-registry-packages-npm-production"}},"2.2.0":{"name":"@automatelab/content-distribution-mcp","version":"2.2.0","keywords":["mcp","content-distribution","devto","hashnode","reddit","bluesky","linkedin","twitter","medium","github-discussions","automation","model-context-protocol"],"author":{"name":"automatelab"},"license":"MIT","_id":"@automatelab/content-distribution-mcp@2.2.0","maintainers":[{"name":"ratamaha","email":"hello@automatelab.tech"}],"homepage":"https://automatelab.tech/products/mcp/content-distribution-mcp/","bugs":{"url":"https://github.com/AutomateLab-tech/content-distribution-mcp/issues"},"bin":{"cdmcp":"dist/index.js","content-distribution-mcp":"dist/index.js"},"dist":{"shasum":"38bb09313f3d9768c6f2208e23e29844f97d052c","tarball":"https://registry.npmjs.org/@automatelab/content-distribution-mcp/-/content-distribution-mcp-2.2.0.tgz","fileCount":59,"integrity":"sha512-hrTg/48ehRmaRyg2UjgvAMxZ2obQ/QCjL68m8Z/MqI/RL0Cg9Zy+N96t4AjzHFBFJjZqXBDL3XRjoPMAWD07wg==","signatures":[{"sig":"MEUCIQCkhntPSVbq7V+rFeZHEdxyRfxAjBiuumr9xLDRPT+ZnQIgfqoekA2nZwx7XDCnTeek+T1YjWfdkstEEu6MqQTHI+I=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":105764},"main":"dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"gitHead":"689f3a184b48501f0d6a6f62dcf8d346c83ac341","scripts":{"build":"tsc","prepare":"npm run build"},"_npmUser":{"name":"ratamaha","email":"hello@automatelab.tech"},"repository":{"url":"git+https://github.com/AutomateLab-tech/content-distribution-mcp.git","type":"git"},"_npmVersion":"11.12.1","description":"Multi-channel content distribution MCP server. Publish one piece of content to DEV.to, Hashnode, GitHub Discussions, Reddit, Bluesky, LinkedIn, Medium, and Twitter with idempotent state.","directories":{},"_nodeVersion":"24.15.0","dependencies":{"zod":"^3.23.0","js-yaml":"^4.1.0","@modelcontextprotocol/sdk":"^1.12.0"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.4.0","@types/node":"^20.0.0","@types/js-yaml":"^4.0.9"},"_npmOperationalInternal":{"tmp":"tmp/content-distribution-mcp_2.2.0_1779360844795_0.83893580350875","host":"s3://npm-registry-packages-npm-production"}},"2.2.1":{"name":"@automatelab/content-distribution-mcp","version":"2.2.1","keywords":["mcp","content-distribution","devto","hashnode","reddit","bluesky","linkedin","twitter","medium","github-discussions","automation","model-context-protocol"],"author":{"name":"automatelab"},"license":"MIT","_id":"@automatelab/content-distribution-mcp@2.2.1","maintainers":[{"name":"ratamaha","email":"hello@automatelab.tech"}],"homepage":"https://automatelab.tech/products/mcp/content-distribution-mcp/","bugs":{"url":"https://github.com/AutomateLab-tech/content-distribution-mcp/issues"},"bin":{"cdmcp":"dist/index.js","content-distribution-mcp":"dist/index.js"},"dist":{"shasum":"86cea86b294da9f6bcb4f84e1914f1b761f7240c","tarball":"https://registry.npmjs.org/@automatelab/content-distribution-mcp/-/content-distribution-mcp-2.2.1.tgz","fileCount":59,"integrity":"sha512-UL/aqVtj2l3z4vTic8Yq2OeqXvYY12/CGqy+kIkRaBjl+QjzNvuZcfOOfSZPnPCSAXWteqHdkzClN0PbWfDqJQ==","signatures":[{"sig":"MEUCIQDIN/a6MAv9qlOwYSejtbR+MuXa4Q84SDuWORr5zS5OvwIgfMH3DIp5GlWiYanzg8Scg2Oxd3Q8ieAxZg+/MQcGHuc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":105920},"main":"dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"gitHead":"689f3a184b48501f0d6a6f62dcf8d346c83ac341","mcpName":"io.github.AutomateLab-tech/content-distribution","scripts":{"build":"tsc","prepare":"npm run build"},"_npmUser":{"name":"ratamaha","email":"hello@automatelab.tech"},"repository":{"url":"git+https://github.com/AutomateLab-tech/content-distribution-mcp.git","type":"git"},"_npmVersion":"11.12.1","description":"Multi-channel content distribution MCP server. Publish one piece of content to DEV.to, Hashnode, GitHub Discussions, Reddit, Bluesky, LinkedIn, Medium, and Twitter with idempotent state.","directories":{},"_nodeVersion":"24.15.0","dependencies":{"zod":"^3.23.0","js-yaml":"^4.1.0","@modelcontextprotocol/sdk":"^1.12.0"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.4.0","@types/node":"^20.0.0","@types/js-yaml":"^4.0.9"},"_npmOperationalInternal":{"tmp":"tmp/content-distribution-mcp_2.2.1_1779373003546_0.9197496795453126","host":"s3://npm-registry-packages-npm-production"}},"2.2.3":{"name":"@automatelab/content-distribution-mcp","version":"2.2.3","keywords":["mcp","content-distribution","devto","hashnode","reddit","bluesky","linkedin","twitter","medium","github-discussions","automation","model-context-protocol"],"author":{"name":"automatelab"},"license":"MIT","_id":"@automatelab/content-distribution-mcp@2.2.3","maintainers":[{"name":"ratamaha","email":"hello@automatelab.tech"}],"homepage":"https://automatelab.tech/products/mcp/content-distribution-mcp/","bugs":{"url":"https://github.com/AutomateLab-tech/content-distribution-mcp/issues"},"bin":{"cdmcp":"dist/index.js","content-distribution-mcp":"dist/index.js"},"dist":{"shasum":"e31672cc183bd384dbe7bf9d76fb1d54692e6d81","tarball":"https://registry.npmjs.org/@automatelab/content-distribution-mcp/-/content-distribution-mcp-2.2.3.tgz","fileCount":59,"integrity":"sha512-KKQuBVjw8p3tyHj7OdhDBF67WJurNahCkkjM+qx/OlOZbb1kqDroKpTAuo673VBHrgSQMGcCziQFhVHl87zIuw==","signatures":[{"sig":"MEUCIQDXPnk+vtLh9xfPGrJM9D8KdxuH0PoDZDCD+qUxqPN1twIgAfUVHAYwsQdCgo5oFcYLsH3a2LSyPzpK9y2+7lXbFY4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":108057},"main":"dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"gitHead":"bba84c3356f6c8c8842fac6d4e8f8adc1da58832","scripts":{"build":"tsc","prepare":"npm run build"},"_npmUser":{"name":"ratamaha","email":"hello@automatelab.tech"},"repository":{"url":"git+https://github.com/AutomateLab-tech/content-distribution-mcp.git","type":"git"},"_npmVersion":"11.12.1","description":"Multi-channel content distribution MCP server. Publish one piece of content to DEV.to, Hashnode, GitHub Discussions, Reddit, Bluesky, LinkedIn, Medium, and Twitter with idempotent state.","directories":{},"_nodeVersion":"24.15.0","dependencies":{"zod":"^3.23.0","js-yaml":"^4.1.0","@modelcontextprotocol/sdk":"^1.12.0"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.4.0","@types/node":"^20.0.0","@types/js-yaml":"^4.0.9"},"_npmOperationalInternal":{"tmp":"tmp/content-distribution-mcp_2.2.3_1780494783605_0.728910537168078","host":"s3://npm-registry-packages-npm-production"}},"2.2.4":{"name":"@automatelab/content-distribution-mcp","version":"2.2.4","keywords":["mcp","content-distribution","devto","hashnode","reddit","bluesky","linkedin","twitter","medium","github-discussions","automation","model-context-protocol"],"author":{"name":"automatelab"},"license":"MIT","_id":"@automatelab/content-distribution-mcp@2.2.4","maintainers":[{"name":"ratamaha","email":"hello@automatelab.tech"}],"homepage":"https://automatelab.tech/products/mcp/content-distribution-mcp/","bugs":{"url":"https://github.com/AutomateLab-tech/content-distribution-mcp/issues"},"bin":{"cdmcp":"dist/index.js","content-distribution-mcp":"dist/index.js"},"dist":{"shasum":"78ece2488c92c76e6961437961b1d28e18b70323","tarball":"https://registry.npmjs.org/@automatelab/content-distribution-mcp/-/content-distribution-mcp-2.2.4.tgz","fileCount":59,"integrity":"sha512-/1muF3ZlJqrI5XDQ/APeHfcutxKcBuBSHr3tvl5LKkwlEViI63qRsaVq1Bz9j3ySadyw+sx4FTwbrCg5fErVSQ==","signatures":[{"sig":"MEUCIQD6jyyLkIah8vv0XQ8uB5ilDBcNPBAY+TWenEde7Vwf2wIgQ36X85eLViDZl3zgzH5PiP6T2WUZx+tre0K5I929MhA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":108057},"main":"dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"gitHead":"260a7ddee46a32f02ae18ba8c9394b6f7d96a93e","scripts":{"build":"tsc","prepare":"npm run build"},"_npmUser":{"name":"ratamaha","email":"hello@automatelab.tech"},"repository":{"url":"git+https://github.com/AutomateLab-tech/content-distribution-mcp.git","type":"git"},"_npmVersion":"11.12.1","description":"Multi-channel content distribution MCP server. Publish one piece of content to DEV.to, Hashnode, GitHub Discussions, Reddit, Bluesky, LinkedIn, Medium, and Twitter with idempotent state.","directories":{},"_nodeVersion":"24.15.0","dependencies":{"zod":"^3.23.0","js-yaml":"^4.1.0","@modelcontextprotocol/sdk":"^1.12.0"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.4.0","@types/node":"^20.0.0","@types/js-yaml":"^4.0.9"},"_npmOperationalInternal":{"tmp":"tmp/content-distribution-mcp_2.2.4_1780497270321_0.6880485586065017","host":"s3://npm-registry-packages-npm-production"}},"3.0.0":{"name":"@automatelab/content-distribution-mcp","version":"3.0.0","description":"Multi-channel content distribution MCP server. Publish one piece of content to DEV.to, Hashnode, GitHub Discussions, Reddit, Bluesky, LinkedIn, Medium, and Twitter with idempotent state.","type":"module","main":"dist/index.js","bin":{"content-distribution-mcp":"dist/index.js","cdmcp":"dist/index.js"},"scripts":{"build":"tsc","prepare":"npm run build"},"dependencies":{"@modelcontextprotocol/sdk":"^1.12.0","js-yaml":"^4.1.0","zod":"^3.23.0"},"devDependencies":{"@types/js-yaml":"^4.0.9","@types/node":"^20.0.0","typescript":"^5.4.0"},"engines":{"node":">=18"},"keywords":["mcp","content-distribution","devto","hashnode","reddit","bluesky","linkedin","twitter","medium","github-discussions","automation","model-context-protocol"],"author":{"name":"automatelab"},"license":"MIT","homepage":"https://automatelab.tech/products/mcp/content-distribution-mcp/","repository":{"type":"git","url":"git+https://github.com/AutomateLab-tech/content-distribution-mcp.git"},"gitHead":"30ffa719f74ebdd0c86fcdfc71192d69c6128432","types":"./dist/index.d.ts","_id":"@automatelab/content-distribution-mcp@3.0.0","bugs":{"url":"https://github.com/AutomateLab-tech/content-distribution-mcp/issues"},"_nodeVersion":"24.15.0","_npmVersion":"11.12.1","dist":{"integrity":"sha512-BZZ4V8FRD+I51zJUnMEvN/cAQ9VfGMDnfLXzGz6JBmTKB/oAydFlkrfCHPPp23+2Yj7j4Y/xLPsJ0FJXnmvRww==","shasum":"31d9df5d5877101f867924d3240493bc2378532a","tarball":"https://registry.npmjs.org/@automatelab/content-distribution-mcp/-/content-distribution-mcp-3.0.0.tgz","fileCount":59,"unpackedSize":108057,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIDuVfxrAtfZZM6OE5nnxCJcB/WAdQeKIyiQZfYsJxeSJAiEA+AU+1wW4N/Rwwz1Dw+qkTKc2yao0sKHtnMZhk3RU0ls="}]},"_npmUser":{"name":"ratamaha","email":"hello@automatelab.tech"},"directories":{},"maintainers":[{"name":"ratamaha","email":"hello@automatelab.tech"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/content-distribution-mcp_3.0.0_1780916531389_0.46340431995751286"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-20T14:06:05.048Z","modified":"2026-06-08T11:02:11.605Z","2.0.1":"2026-05-20T14:06:05.332Z","2.1.0":"2026-05-20T15:21:07.091Z","2.2.0":"2026-05-21T10:54:04.952Z","2.2.1":"2026-05-21T14:16:43.728Z","2.2.3":"2026-06-03T13:53:03.747Z","2.2.4":"2026-06-03T14:34:30.463Z","3.0.0":"2026-06-08T11:02:11.514Z"},"bugs":{"url":"https://github.com/AutomateLab-tech/content-distribution-mcp/issues"},"author":{"name":"automatelab"},"license":"MIT","homepage":"https://automatelab.tech/products/mcp/content-distribution-mcp/","keywords":["mcp","content-distribution","devto","hashnode","reddit","bluesky","linkedin","twitter","medium","github-discussions","automation","model-context-protocol"],"repository":{"type":"git","url":"git+https://github.com/AutomateLab-tech/content-distribution-mcp.git"},"description":"Multi-channel content distribution MCP server. Publish one piece of content to DEV.to, Hashnode, GitHub Discussions, Reddit, Bluesky, LinkedIn, Medium, and Twitter with idempotent state.","maintainers":[{"name":"ratamaha","email":"hello@automatelab.tech"}],"readme":"# content-distribution-mcp\r\n\r\n**Publish your content everywhere—without rewriting for every platform.**\r\n\r\nA 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.\r\n\r\n## The Problem It Solves\r\n\r\nCreating and publishing content at scale is friction-heavy:\r\n- **Different formats**: Reddit strips formatting, Twitter has character limits, DEV.to supports embeds and rich media. Each needs customized copy.\r\n- **Platform rules**: Subreddits enforce cooldowns and flair requirements. Communities have posting patterns and automoderator gates. LinkedIn suppresses external links.\r\n- **State chaos**: Which posts went live where? What if a publish fails halfway? Did that Reddit post get auto-removed by spam filters?\r\n\r\nThis MCP handles distribution complexity. Write your core message once, generate platform-specific variants, publish everywhere safely.\r\n\r\n## How It Works\r\n\r\n1. **Your agent** generates channel-specific copy variants (rewritten titles, trimmed text, platform-appropriate tags, audience-matched tone).\r\n2. **This MCP** publishes each variant with idempotency, OAuth, API retries, and scheduling—enforcing platform constraints automatically.\r\n3. **You control** which platforms get what. The MCP returns per-channel hints (character limits, tag vocabularies, cooldowns) but leaves creative decisions to you.\r\n\r\nNo LLM calls inside. No walled-in agents. Just a clean API for multi-platform content distribution at scale.\r\n\r\n## Install\r\n\r\n```bash\r\nnpx @automatelab/content-distribution-mcp\r\n```\r\n\r\nOr add it permanently to your MCP host.\r\n\r\n## Wire into your MCP host\r\n\r\n**Claude Code** — add to `.claude/mcp.json`:\r\n\r\n```json\r\n{\r\n  \"mcpServers\": {\r\n    \"content-distribution\": {\r\n      \"command\": \"npx\",\r\n      \"args\": [\"-y\", \"@automatelab/content-distribution-mcp\"]\r\n    }\r\n  }\r\n}\r\n```\r\n\r\n**Claude Desktop** — add to `claude_desktop_config.json`:\r\n\r\n```json\r\n{\r\n  \"mcpServers\": {\r\n    \"content-distribution\": {\r\n      \"command\": \"npx\",\r\n      \"args\": [\"-y\", \"@automatelab/content-distribution-mcp\"]\r\n    }\r\n  }\r\n}\r\n```\r\n\r\n**n8n** — use the MCP Client node, point it at `npx @automatelab/content-distribution-mcp` over stdio.\r\n\r\n**Cursor / Windsurf / any MCP host** — same `npx -y content-distribution-mcp` pattern.\r\n\r\n## Configure credentials\r\n\r\nThe server reads credentials from a **Distribution Profile** stored in `~/.distribution-mcp/profiles.yaml`:\r\n\r\n```yaml\r\n# ~/.distribution-mcp/profiles.yaml\r\ndefault:\r\n  credentials:\r\n    DEV_TO_API_KEY: \"your-devto-api-key\"\r\n    HASHNODE_TOKEN: \"your-hashnode-token\"\r\n    HASHNODE_PUBLICATION_ID: \"your-pub-id\"\r\n    GITHUB_TOKEN: \"ghp_...\"\r\n    GITHUB_DISCUSSION_REPO: \"owner/repo\"\r\n    REDDIT_CLIENT_ID: \"...\"\r\n    REDDIT_CLIENT_SECRET: \"...\"\r\n    REDDIT_USERNAME: \"...\"\r\n    REDDIT_PASSWORD: \"...\"\r\n    BLUESKY_IDENTIFIER: \"you.bsky.social\"\r\n    BLUESKY_PASSWORD: \"...\"\r\n  subreddits:\r\n    - ClaudeAI\r\n    - LocalLLaMA\r\n```\r\n\r\nOnly set credentials for channels you intend to use. LinkedIn, Medium, and Twitter/X return `needs_browser` with a compose URL — no credentials needed.\r\n\r\n## MCP tool surface\r\n\r\nEight 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.\r\n\r\n| Tool | Purpose |\r\n|---|---|\r\n| `post_publish` | Immediate publish; idempotent on `(content.id, channel)` |\r\n| `post_schedule` | Queue variants for `schedule_at`, publish the rest immediately |\r\n| `post_drain` | Fire all scheduled posts due now — run from cron |\r\n| `post_status` | Per-channel state for a content piece or channel |\r\n| `post_unpublish` | Best-effort delete (DEV.to sets unpublished; others vary) |\r\n| `channel_hints` | Per-channel metadata: char limits, Markdown support, tag vocab |\r\n| `profile_list` | Names of configured distribution profiles |\r\n| `subreddit_list` | Subreddit Catalog: cooldowns, flair vocab, last-posted |\r\n\r\n> **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.\r\n\r\n## Channels\r\n\r\n| Channel key | Tier | Auth |\r\n|---|---|---|\r\n| `devto` | Auto | `DEV_TO_API_KEY` |\r\n| `hashnode` | Auto | `HASHNODE_TOKEN` + `HASHNODE_PUBLICATION_ID` |\r\n| `github_discussions` | Auto | `GITHUB_TOKEN` + `GITHUB_DISCUSSION_REPO` |\r\n| `reddit` | Auto-gated | `REDDIT_CLIENT_ID/SECRET/USERNAME/PASSWORD` |\r\n| `bluesky` | Auto | `BLUESKY_IDENTIFIER` + `BLUESKY_PASSWORD` |\r\n| `linkedin` | Browser fallback | returns `needs_browser` + compose URL |\r\n| `medium` | Browser fallback | returns `needs_browser` + compose URL |\r\n| `twitter` / `x` | Browser fallback | returns `needs_browser` + compose URL |\r\n\r\n## Example agent call\r\n\r\n```jsonc\r\n// post_publish tool\r\n{\r\n  \"content\": {\r\n    \"id\": \"n8n-webhook-setup@2026-05-20\",\r\n    \"title\": \"How to set up an n8n webhook\",\r\n    \"body_md\": \"...\",\r\n    \"tags\": [\"automation\", \"n8n\", \"tutorial\"],\r\n    \"canonical_url\": \"https://yourblog.com/n8n-webhook-setup\",\r\n    \"author\": \"You\"\r\n  },\r\n  \"variants\": [\r\n    {\r\n      \"channel\": \"devto:main\",\r\n      \"title\": \"How to set up an n8n webhook\",\r\n      \"body\": \"...\",\r\n      \"tags\": [\"automation\", \"n8n\", \"tutorial\", \"devops\"],\r\n      \"canonical_url\": \"https://yourblog.com/n8n-webhook-setup\",\r\n      \"extras\": {}\r\n    },\r\n    {\r\n      \"channel\": \"reddit:ClaudeAI\",\r\n      \"title\": \"Built a webhook automation with n8n\",\r\n      \"body\": \"Here's how I set it up...\",\r\n      \"tags\": [],\r\n      \"extras\": { \"flair\": \"Project\" }\r\n    }\r\n  ],\r\n  \"profile_name\": \"default\"\r\n}\r\n```\r\n\r\n## Idempotency\r\n\r\nRe-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.\r\n\r\n## Scheduling\r\n\r\nVariants 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:\r\n\r\n```bash\r\n# fire due posts every 5 minutes\r\n*/5 * * * * npx -y content-distribution-mcp drain\r\n```\r\n\r\nOr call the `post_drain` MCP tool directly from an agent.\r\n\r\n## Environment variables\r\n\r\n| Variable | Default | Purpose |\r\n|---|---|---|\r\n| `DISTRIBUTION_BACKEND` | `yaml` | State backend (`yaml` only in v1) |\r\n| `DISTRIBUTION_BACKEND_DIR` | `~/.distribution-mcp` | Directory for YAML state files |\r\n\r\n## Requirements\r\n\r\n- Node.js 18 or later\r\n\r\n## Architecture\r\n\r\n```\r\nAgent (Claude Code / n8n / Cursor / any MCP host)\r\n  │  generates per-channel copy, calls MCP tools\r\n  ▼\r\ncontent-distribution-mcp  (this package, stdio transport)\r\n  │  no LLM calls — pure I/O\r\n  ├── adapters/   devto · hashnode · github-discussions · reddit · bluesky · browser\r\n  └── backends/   yaml (post log · profiles · schedule queue · subreddit catalog)\r\n```\r\n\r\n## Works with any MCP client\r\n\r\nNo Anthropic-specific code anywhere. Verify:\r\n\r\n```bash\r\ngrep -ri \"anthropic\" node_modules/content-distribution-mcp/dist/  # returns nothing\r\n```\r\n\r\n## Part of the AutomateLab stack\r\n\r\n- [agency-os](https://github.com/AutomateLab-tech/agency-os) — control plane\r\n- **content-distribution-mcp** — this package\r\n- [automatelab.tech](https://automatelab.tech) — blog and tutorials\r\n\r\n## License\r\n\r\nMIT\r\n","readmeFilename":"README.md"}