Building a Social Publishing MCP Server: What We Learned

June 29, 2026 · ReplyNodes Team

We get asked a fair amount, mostly by other builders, how we approached designing ReplyNodes' MCP server. Some of it was straightforward; some of it we got wrong on the first pass. Notes below.

Start from workflows, not from your data model

The obvious first instinct is to expose your existing REST resources as MCP tools 1:1 — get_post, create_post, update_post, delete_post. We tried that early on and it produced a tool surface that was technically complete and practically useless: an agent given create_post has no idea it's supposed to check character limits per platform, or that this particular channel requires approval before anything goes live.

The fix was designing tools around the actual workflow steps — draft_post (handles per-channel formatting), request_approval (only callable on drafts, routes to the right reviewer), publish_post (only callable on approved drafts, or on channels configured for auto-publish) — rather than around database operations. See Agent-native vs. API-first: what's actually different for the reasoning behind this, and the full tool list in the API reference.

Put guardrails in the tool, not in documentation

Early versions had a publish_post tool with a docstring warning "only call this after approval is granted for approval-required channels." That's a prompt-injection-shaped hole waiting to happen, and also just unreliable — models don't reliably follow docstring caveats under all conditions. We moved the check server-side: publish_post returns an error if the channel requires approval and none exists, full stop. The agent can't be talked into skipping it because there's no code path that allows it. Full detail in Approval workflows for AI-generated social content.

Keep the tool count small and the descriptions precise

We initially over-decomposed — separate tools for get_channel_by_id, get_channel_by_name, list_all_channels, list_active_channels. Most agents did fine picking the right one, but it added surface area for mistakes and made the tool list harder to reason about. Consolidating into fewer tools with clear parameters (list_channels(status?: "active" | "all")) reduced errors without losing functionality.

Test with the agents your users will actually connect

MCP is a standard, but agents differ in how aggressively they call tools, how they handle tool errors, and how much they retry. We test against Claude Code, ChatGPT, and a couple of other MCP clients specifically, rather than assuming "MCP-compliant" means "behaves identically everywhere." If you're building your own MCP server, this is worth doing before you ship — see our documentation for the tool schemas we settled on, or read about what MCP actually is if you're earlier in the process than we were.