<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: PipepostDev</title>
    <description>The latest articles on DEV Community by PipepostDev (@pipepost).</description>
    <link>https://dev.to/pipepost</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3877847%2Fba2159c7-e34e-48e0-abc6-e85fa5af2b85.png</url>
      <title>DEV Community: PipepostDev</title>
      <link>https://dev.to/pipepost</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pipepost"/>
    <language>en</language>
    <item>
      <title>Pipepost v0.9.0 — Substack publishing + the agent-loop transcript</title>
      <dc:creator>PipepostDev</dc:creator>
      <pubDate>Thu, 16 Apr 2026 19:04:55 +0000</pubDate>
      <link>https://dev.to/pipepost/pipepost-v090-substack-publishing-the-agent-loop-transcript-2cpg</link>
      <guid>https://dev.to/pipepost/pipepost-v090-substack-publishing-the-agent-loop-transcript-2cpg</guid>
      <description>&lt;h1&gt;
  
  
  Pipepost v0.9.0 — Substack publishing + the agent-loop transcript
&lt;/h1&gt;

&lt;p&gt;You can now publish to &lt;strong&gt;Substack&lt;/strong&gt; from Claude Code. That makes 6 CMS platforms in a single MCP server: Dev.to, Ghost, Hashnode, WordPress, Medium, and Substack.&lt;/p&gt;

&lt;p&gt;But the more interesting part of v0.9.0 isn't a new platform. It's a &lt;a href="https://github.com/MendleM/Pipepost/blob/main/docs/demo/agent-loop.md" rel="noopener noreferrer"&gt;transcript&lt;/a&gt; showing what an &lt;em&gt;agent-loop&lt;/em&gt; publishing pipeline actually looks like.&lt;/p&gt;

&lt;h2&gt;
  
  
  What an agent loop replaces
&lt;/h2&gt;

&lt;p&gt;If you publish to multiple platforms today, the manual flow is roughly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open Dev.to, paste, format, tag, save draft&lt;/li&gt;
&lt;li&gt;Open Ghost admin, paste, format, set canonical URL, save draft&lt;/li&gt;
&lt;li&gt;Open Hashnode, paste, format, set canonical URL, save draft&lt;/li&gt;
&lt;li&gt;Open WordPress, paste, format, set canonical URL, save draft&lt;/li&gt;
&lt;li&gt;Open Substack, paste, format, save draft&lt;/li&gt;
&lt;li&gt;Open three SEO tools — one for scoring, one for meta tags, one for schema&lt;/li&gt;
&lt;li&gt;Open Twitter compose, write a thread of 4 tweets&lt;/li&gt;
&lt;li&gt;Open LinkedIn, write a professional version of the same post&lt;/li&gt;
&lt;li&gt;Open Bluesky, write a 287-character version&lt;/li&gt;
&lt;li&gt;Open Bing Webmaster Tools, paste the URL, click submit&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Realistic time: 45 to 90 minutes of context switching.&lt;/p&gt;

&lt;p&gt;The agent-loop version of that flow is one prompt:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Take this draft, audit it, score it for SEO, fix any issues, cross-publish to Dev.to, Ghost, Hashnode, WordPress and Substack as drafts with the Dev.to URL as the canonical, generate Twitter + LinkedIn + Bluesky posts, and submit the Dev.to URL to IndexNow.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Claude Code chains the calls, threads the canonical URL between them, prints the output, and asks if you want to flip the drafts to published.&lt;/p&gt;

&lt;p&gt;The full annotated transcript is in the repo: &lt;a href="https://github.com/MendleM/Pipepost/blob/main/docs/demo/agent-loop.md" rel="noopener noreferrer"&gt;docs/demo/agent-loop.md&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Substack piece
&lt;/h2&gt;

&lt;p&gt;Substack does not have a public API. The &lt;code&gt;publish&lt;/code&gt; tool now talks to Substack's reverse-engineered endpoints:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;POST /api/v1/drafts&lt;/code&gt; to create&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;POST /api/v1/drafts/{id}/publish&lt;/code&gt; to publish&lt;/li&gt;
&lt;li&gt;Cookie auth via &lt;code&gt;connect.sid&lt;/code&gt; (DevTools → Application → Cookies → &lt;code&gt;substack.com&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Markdown converted to ProseMirror documents (paragraphs, headings, code blocks, blockquotes, bullet lists, inline bold/italic/code/links)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;user_id&lt;/code&gt; resolved from &lt;code&gt;/api/v1/user/profile/self&lt;/code&gt; on first publish, then cached in &lt;code&gt;~/.pipepost/config.json&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Setup:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx pipepost-mcp init
&lt;span class="c"&gt;# then in Claude Code:&lt;/span&gt;
&lt;span class="c"&gt;# setup platform=substack connect_sid=&amp;lt;cookie&amp;gt; publication_url=https://you.substack.com&lt;/span&gt;
&lt;span class="c"&gt;# publish platform=substack title="..." content="..." status=draft&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What v0.9.0 ships with
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;30 MCP tools&lt;/li&gt;
&lt;li&gt;6 CMS publish targets (Dev.to, Ghost, Hashnode, WordPress, Medium, Substack)&lt;/li&gt;
&lt;li&gt;4 direct social broadcast targets (Bluesky, Mastodon, LinkedIn, X)&lt;/li&gt;
&lt;li&gt;4 SEO tools (scoring, meta, schema, IndexNow)&lt;/li&gt;
&lt;li&gt;4 draft tools (save, list, get, delete)&lt;/li&gt;
&lt;li&gt;4 Bluesky listening + reply tools&lt;/li&gt;
&lt;li&gt;Cover image search (Unsplash)&lt;/li&gt;
&lt;li&gt;Frontmatter generator for 7 SSGs&lt;/li&gt;
&lt;li&gt;Content audit + link checker&lt;/li&gt;
&lt;li&gt;Repurpose + generate-social-posts&lt;/li&gt;
&lt;li&gt;Unified analytics across all configured platforms&lt;/li&gt;
&lt;li&gt;446 tests, MIT licensed, no telemetry&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Install:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx pipepost-mcp init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Read the transcript: &lt;a href="https://github.com/MendleM/Pipepost/blob/main/docs/demo/agent-loop.md" rel="noopener noreferrer"&gt;docs/demo/agent-loop.md&lt;/a&gt;&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>claudecode</category>
      <category>substack</category>
      <category>typescript</category>
    </item>
    <item>
      <title>What an MCP server for content publishing actually needs to do</title>
      <dc:creator>PipepostDev</dc:creator>
      <pubDate>Thu, 16 Apr 2026 17:03:24 +0000</pubDate>
      <link>https://dev.to/pipepost/what-an-mcp-server-for-content-publishing-actually-needs-to-do-51oc</link>
      <guid>https://dev.to/pipepost/what-an-mcp-server-for-content-publishing-actually-needs-to-do-51oc</guid>
      <description>&lt;p&gt;An MCP server for content publishing turns your AI assistant into a publishing pipeline. You write a markdown draft, the assistant calls the server's tools, and the post lands on Dev.to, Hashnode, Ghost, WordPress, Medium — plus broadcasts to Bluesky, Mastodon, LinkedIn, and X — without you leaving the conversation.&lt;/p&gt;

&lt;p&gt;This post is the design rationale. What does a content-publishing MCP server actually need to do, why does the MCP architecture fit this problem better than a CLI or a SaaS, and what separates a good one from a thin API wrapper.&lt;/p&gt;

&lt;h2&gt;
  
  
  What "content publishing" means in practice
&lt;/h2&gt;

&lt;p&gt;A complete content-publishing pipeline does five things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Drafts&lt;/strong&gt; — write or edit markdown locally, with frontmatter for metadata&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scores&lt;/strong&gt; — SEO-check the post (readability, headings, keyword density, meta description) before it goes anywhere&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enriches&lt;/strong&gt; — generate JSON-LD schema, canonical URLs, Open Graph tags&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Publishes&lt;/strong&gt; — send the post to one or more CMS platforms with the right field mapping per platform&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Broadcasts&lt;/strong&gt; — generate platform-specific social copy and post it to whichever networks you care about&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A CLI can do all five but you have to remember which command flag does what. A SaaS can do all five but it owns your drafts and your publishing history. An MCP server lets your AI assistant do all five &lt;strong&gt;using natural language&lt;/strong&gt; while keeping your drafts as files you own.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why MCP fits this problem
&lt;/h2&gt;

&lt;p&gt;Content publishing is where MCP shines because every step is a discrete tool call with clear inputs and outputs.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Score this post for SEO" → &lt;code&gt;seo_score&lt;/code&gt; returns 0-100 + recommendations&lt;/li&gt;
&lt;li&gt;"Generate JSON-LD for it" → &lt;code&gt;generate_schema&lt;/code&gt; returns the markup&lt;/li&gt;
&lt;li&gt;"Publish to dev.to as a draft" → &lt;code&gt;devto_post&lt;/code&gt; returns the draft URL&lt;/li&gt;
&lt;li&gt;"Now post a thread about it on Bluesky" → &lt;code&gt;bluesky_post&lt;/code&gt; returns the post URL&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each tool is independently testable. Each tool returns structured data the assistant can reason about. The assistant can chain them in whatever order makes sense ("score it, fix anything below 80, publish, then broadcast"), and the user never has to remember command-line syntax.&lt;/p&gt;

&lt;p&gt;This is also why MCP beats Zapier or Make for content workflows specifically. Zapier triggers are event-based; you set up a flow and it runs unattended. Content publishing is the opposite — the human (or the assistant on the human's behalf) decides post by post what to do. MCP is the right shape for the latter.&lt;/p&gt;

&lt;h2&gt;
  
  
  What separates a good content-publishing MCP server from a thin wrapper
&lt;/h2&gt;

&lt;p&gt;If your "MCP server for content publishing" is one tool that takes &lt;code&gt;{platform, content}&lt;/code&gt; and POSTs to whichever API, you have a thin wrapper. That's not enough.&lt;/p&gt;

&lt;p&gt;The bar:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Per-platform field handling.&lt;/strong&gt; Dev.to wants &lt;code&gt;tags&lt;/code&gt; (max 4, no spaces), &lt;code&gt;canonical_url&lt;/code&gt;, &lt;code&gt;series&lt;/code&gt;, &lt;code&gt;cover_image&lt;/code&gt; (1000x420). Hashnode wants &lt;code&gt;tags&lt;/code&gt; as full objects with slugs, a &lt;code&gt;coverImageOptions&lt;/code&gt; field, and &lt;code&gt;publicationId&lt;/code&gt;. WordPress wants &lt;code&gt;status&lt;/code&gt;, &lt;code&gt;categories&lt;/code&gt; (numeric IDs not names), and an authentication header that's distinct from the standard Bearer pattern. Each platform has its own quirks. A good MCP server hides them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Auth handling that actually works.&lt;/strong&gt; Different platforms have different auth models: API keys (Dev.to, Hashnode), application passwords (WordPress), Admin API keys with JWT signing (Ghost), OAuth 2.0 (LinkedIn, Medium), OAuth 1.0a (X). A good server stores credentials safely and surfaces clear errors when they're wrong or expired.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Canonical URLs handled by default.&lt;/strong&gt; When you cross-post to four platforms, you have one canonical URL — your own blog. Every other platform should point its &lt;code&gt;canonical_url&lt;/code&gt; field at the original. Good MCP servers wire this automatically; bad ones leave you to figure it out per platform.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SEO scoring as a first-class tool, not an afterthought.&lt;/strong&gt; "Did the post hit a reasonable readability score" is a five-second check that catches drafts that aren't ready. A content-publishing MCP server that doesn't include SEO scoring is treating publishing as a destination instead of a quality gate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Schema.org JSON-LD generated from the markdown.&lt;/strong&gt; Search engines want structured data. Generating Article-type JSON-LD from a markdown post is mechanical: title, description, date, author, word count. A good MCP server emits it; you copy it into your blog template once and you're done.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Broadcast tools alongside publish tools.&lt;/strong&gt; Content gets seen because someone shared it. A content-publishing MCP server should generate platform-specific social copy and let the assistant post it to Bluesky/Mastodon/LinkedIn/X in the same conversation as the publish step.&lt;/p&gt;

&lt;h2&gt;
  
  
  The reference implementation
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/MendleM/Pipepost" rel="noopener noreferrer"&gt;Pipepost&lt;/a&gt; is the open-source MCP server that hits all of those criteria today. Five CMS clients (Dev.to, Hashnode, Ghost, WordPress, Medium), four social broadcast tools (Bluesky, Mastodon, LinkedIn, X), SEO scoring, schema.org generation, canonical URL handling, link checking, draft management, content audit, content repurposing into social copy. 30 tools total, 414 tests, runs over stdio in any MCP client.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; pipepost-mcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then add to your MCP client config:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"pipepost"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"-y"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"pipepost-mcp"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  When a content-publishing MCP server is the wrong tool
&lt;/h2&gt;

&lt;p&gt;If your publishing workflow is one platform, no SEO requirements, and the official web editor works fine, you don't need an MCP server. Open the web app, paste, publish.&lt;/p&gt;

&lt;p&gt;If your team has a content calendar, a copywriter, an editor, a designer reviewing covers — you need a CMS plus a workflow tool, not an MCP server. MCP serves the dev-and-marketer-of-one model where the same person is writing, editing, publishing, and promoting.&lt;/p&gt;

&lt;p&gt;For everyone in between (technical founders, indie devs, dev-rel teams of one), an MCP server collapses the publishing step into a sentence. That's the entire pitch.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/MendleM/Pipepost" rel="noopener noreferrer"&gt;Source on GitHub&lt;/a&gt;. &lt;a href="https://www.npmjs.com/package/pipepost-mcp" rel="noopener noreferrer"&gt;npm&lt;/a&gt;. Available on the &lt;a href="https://registry.modelcontextprotocol.io/servers/io.github.MendleM/pipepost" rel="noopener noreferrer"&gt;MCP Registry&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>publishing</category>
      <category>claude</category>
      <category>devtools</category>
    </item>
    <item>
      <title>Publish to Dev.to from Claude Code in one MCP call</title>
      <dc:creator>PipepostDev</dc:creator>
      <pubDate>Thu, 16 Apr 2026 16:54:23 +0000</pubDate>
      <link>https://dev.to/pipepost/publish-to-devto-from-claude-code-in-one-mcp-call-597e</link>
      <guid>https://dev.to/pipepost/publish-to-devto-from-claude-code-in-one-mcp-call-597e</guid>
      <description>&lt;p&gt;If you live inside Claude Code (or any MCP client), the trip from "draft is ready" to "post is live on Dev.to" is friction. You leave the editor, open the Dev.to web app, paste the markdown, fix the canonical URL, set tags, hit publish. That's a workflow you do less often when you're tired.&lt;/p&gt;

&lt;p&gt;Here's the same trip without leaving Claude Code.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you need
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;a href="https://dev.to/settings/extensions"&gt;Dev.to API key&lt;/a&gt; — generate it in two clicks under "DEV Community API Keys".&lt;/li&gt;
&lt;li&gt;The &lt;a href="https://github.com/MendleM/Pipepost" rel="noopener noreferrer"&gt;Pipepost MCP server&lt;/a&gt; — &lt;code&gt;npm install -g pipepost-mcp&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Claude Code, Cursor, Windsurf, or any MCP client wired to that server.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  One-time setup
&lt;/h2&gt;

&lt;p&gt;In your MCP client, add Pipepost as a server. For Claude Code, add this to your &lt;code&gt;mcp.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"pipepost"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"-y"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"pipepost-mcp"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then run setup once to save your Dev.to API key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;setup &lt;span class="nv"&gt;platform&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"devto"&lt;/span&gt; &lt;span class="nv"&gt;credentials&lt;/span&gt;&lt;span class="o"&gt;={&lt;/span&gt;api_key: &lt;span class="s2"&gt;"YOUR_KEY"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key gets written to &lt;code&gt;~/.pipepost/config.json&lt;/code&gt; and used for every future call.&lt;/p&gt;

&lt;h2&gt;
  
  
  Publishing a draft
&lt;/h2&gt;

&lt;p&gt;Open the markdown file you've been writing in Claude Code. Tell the assistant:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Publish this to Dev.to as a draft.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Pipepost reads the file, calls Dev.to's POST &lt;code&gt;/api/articles&lt;/code&gt; with &lt;code&gt;published: false&lt;/code&gt;, and returns the draft URL. You can review it on Dev.to before flipping the switch.&lt;/p&gt;

&lt;h2&gt;
  
  
  Publishing live
&lt;/h2&gt;

&lt;p&gt;Same flow, but tell it to publish (or pass &lt;code&gt;published=true&lt;/code&gt;). The article goes live immediately and Pipepost returns the canonical URL it landed on.&lt;/p&gt;

&lt;h2&gt;
  
  
  The detail that matters: canonical URLs
&lt;/h2&gt;

&lt;p&gt;If you're cross-posting (Dev.to + your own blog + Hashnode + Medium), Google needs to know which URL is the source. Dev.to honors a &lt;code&gt;canonical_url&lt;/code&gt; field — set it to your own blog post URL and Dev.to will tell search engines "this content lives at the canonical URL, not here."&lt;/p&gt;

&lt;p&gt;Pipepost auto-wires this. If you have a blog at &lt;code&gt;pipepost.dev/blog&lt;/code&gt;, you can pass &lt;code&gt;canonical_url="https://pipepost.dev/blog/my-slug"&lt;/code&gt; and Pipepost forwards it to Dev.to. The result: the Dev.to copy still ranks for branded queries, but doesn't compete with your own blog for the same content.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tags, cover image, and series
&lt;/h2&gt;

&lt;p&gt;Pipepost passes through everything Dev.to's API supports:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;tags&lt;/code&gt; — up to 4, no spaces&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;cover_image&lt;/code&gt; — full URL to a hosted image (1000x420 is the recommended ratio)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;series&lt;/code&gt; — group multi-part posts under one series name&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;description&lt;/code&gt; — overrides the auto-generated meta description&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The full schema is in the Pipepost source: &lt;a href="https://github.com/MendleM/Pipepost/blob/main/src/cms/devto.ts" rel="noopener noreferrer"&gt;src/cms/devto.ts&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this is good for (and what it isn't)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Good for:&lt;/strong&gt; developer-blogger workflows where you write in markdown locally, want low-friction publishing, and want canonical URLs handled correctly the first time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Not for:&lt;/strong&gt; cases where Dev.to-specific features (like the rich-text editor's image upload) matter to you. The API publishes raw markdown — if you need the WYSIWYG, use the web app.&lt;/p&gt;

&lt;h2&gt;
  
  
  What about the other platforms?
&lt;/h2&gt;

&lt;p&gt;Pipepost ships clients for Hashnode, Ghost, WordPress, and Medium too. The same MCP call structure works:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;hashnode_post &lt;span class="nv"&gt;body_markdown&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt; &lt;span class="nv"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt;
ghost_post &lt;span class="nv"&gt;html&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt; &lt;span class="nv"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt;
wordpress_post &lt;span class="nv"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt; &lt;span class="nv"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt;
medium_post &lt;span class="nv"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt; &lt;span class="nv"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And for promotion: &lt;code&gt;bluesky_post&lt;/code&gt;, &lt;code&gt;mastodon_post&lt;/code&gt;, &lt;code&gt;linkedin_post&lt;/code&gt;, &lt;code&gt;x_post&lt;/code&gt; are all in the same server.&lt;/p&gt;

&lt;h2&gt;
  
  
  The point
&lt;/h2&gt;

&lt;p&gt;Publishing to Dev.to from Claude Code isn't novel — anyone with a curl call and the API docs can do it. The point of an MCP server is removing the steps between "I have a draft" and "it's live": no shell, no API key copy-paste, no checking that you got the canonical URL right, no remembering which tag format Dev.to wants.&lt;/p&gt;

&lt;p&gt;If you publish more than once a month, the math works out fast.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/MendleM/Pipepost" rel="noopener noreferrer"&gt;Source on GitHub&lt;/a&gt;. &lt;a href="https://www.npmjs.com/package/pipepost-mcp" rel="noopener noreferrer"&gt;npm&lt;/a&gt;. PRs welcome.&lt;/p&gt;

</description>
      <category>devto</category>
      <category>mcp</category>
      <category>claude</category>
      <category>publishing</category>
    </item>
    <item>
      <title>Pipepost v0.8.0: LinkedIn + X posting from any MCP client</title>
      <dc:creator>PipepostDev</dc:creator>
      <pubDate>Thu, 16 Apr 2026 16:48:27 +0000</pubDate>
      <link>https://dev.to/pipepost/pipepost-v080-linkedin-x-posting-from-any-mcp-client-1efa</link>
      <guid>https://dev.to/pipepost/pipepost-v080-linkedin-x-posting-from-any-mcp-client-1efa</guid>
      <description>&lt;p&gt;Pipepost is an MCP server that lets your AI assistant publish content end-to-end: SEO scoring, multi-platform publishing, and social broadcast. v0.8.0 adds the two surfaces that were missing — LinkedIn and X — so an MCP client can now reach all the developer-relevant networks without leaving the conversation.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's in v0.8.0
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;linkedin_post&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Posts to LinkedIn via the &lt;code&gt;/v2/ugcPosts&lt;/code&gt; endpoint. On first call, Pipepost looks up your person URN from &lt;code&gt;/v2/userinfo&lt;/code&gt; and caches it back to your config so subsequent calls skip the round trip. 3000 character limit enforced before the API call so you don't burn quota on a malformed post.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;linkedin_post text="Shipping is the only feature that compounds."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;x_post&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Single tweet or reply-chained thread via X v2 &lt;code&gt;/tweets&lt;/code&gt;. OAuth 1.0a HMAC-SHA1 signing built in (the X v2 API still requires it for user-context writes). 280 grapheme limit per post — graphemes, not chars, so emoji don't overcount.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;x_post text="One. Idea. Per. Tweet."
x_post posts=["thread starts here", "second tweet replies", "third closes"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The setup friction problem
&lt;/h2&gt;

&lt;p&gt;LinkedIn and X both have OAuth flows that bury you in a forest of scopes, redirect URIs, and token exchanges. v0.8.0 ships &lt;code&gt;scripts/linkedin-auth.mjs&lt;/code&gt; to collapse the LinkedIn flow into a single command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;LINKEDIN_CLIENT_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;xxx &lt;span class="nv"&gt;LINKEDIN_CLIENT_SECRET&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;yyy pnpm run linkedin:auth
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It spins up a local HTTP server, opens your browser to LinkedIn's consent page, captures the redirect, exchanges the code for an access token, fetches your person URN, and prints a ready-to-paste &lt;code&gt;setup&lt;/code&gt; command for Pipepost. No copy-pasting tokens between tabs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why a thread chainer
&lt;/h2&gt;

&lt;p&gt;X's API doesn't have a "post a thread" endpoint — you post each tweet individually with &lt;code&gt;reply.in_reply_to_tweet_id&lt;/code&gt; pointing at the previous one. &lt;code&gt;x_post&lt;/code&gt; accepts a &lt;code&gt;posts&lt;/code&gt; array and chains the replies for you, aborting cleanly if any post fails (so you don't end up with a half-published thread).&lt;/p&gt;

&lt;h2&gt;
  
  
  What I learned about both APIs while building this
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;LinkedIn:&lt;/strong&gt; the modern way to identify yourself is OpenID Connect (&lt;code&gt;openid profile&lt;/code&gt; scopes, &lt;code&gt;/v2/userinfo&lt;/code&gt; returns the &lt;code&gt;sub&lt;/code&gt; field, your URN is &lt;code&gt;urn:li:person:&amp;lt;sub&amp;gt;&lt;/code&gt;). The old &lt;code&gt;/v2/me&lt;/code&gt; endpoint requires the deprecated &lt;code&gt;r_liteprofile&lt;/code&gt; scope. Use the new path.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LinkedIn (cont):&lt;/strong&gt; posting from a company page requires &lt;code&gt;w_organization_social&lt;/code&gt; instead of &lt;code&gt;w_member_social&lt;/code&gt;, which gates behind LinkedIn Marketing Developer Platform approval (usually 1–4 weeks). v0.8.0 supports personal posting today; company posting will land when MDP approval comes through.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;X:&lt;/strong&gt; the v2 &lt;code&gt;/tweets&lt;/code&gt; endpoint accepts JSON bodies but you sign the URL parameters (none, in this case) — the JSON body itself is NOT part of the signature base string. This trips up everyone implementing OAuth 1.0a for v2. The x.ts module in this repo handles it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;X (cont):&lt;/strong&gt; &lt;code&gt;encodeURIComponent&lt;/code&gt; does not percent-encode &lt;code&gt;!&lt;/code&gt;, &lt;code&gt;*&lt;/code&gt;, &lt;code&gt;'&lt;/code&gt;, &lt;code&gt;(&lt;/code&gt;, &lt;code&gt;)&lt;/code&gt; — but RFC 3986 (and OAuth 1.0a) requires them encoded. The signature will be wrong if you skip this. There's a one-line &lt;code&gt;rfc3986()&lt;/code&gt; helper in the source.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get it
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; pipepost-mcp@0.8.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or via the &lt;a href="https://registry.modelcontextprotocol.io/servers/io.github.MendleM/pipepost" rel="noopener noreferrer"&gt;MCP Registry&lt;/a&gt;. Source on &lt;a href="https://github.com/MendleM/Pipepost" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Pipepost is built in the open. If you ship MCP servers and want to compare notes on these patterns, the issues tracker on GitHub is open.&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>claude</category>
      <category>publishing</category>
      <category>devtools</category>
    </item>
  </channel>
</rss>
