Strand CMS
Articlemcp

Publishing MCP Tools: create_draft to publish_post

This article is published by Strand CMS (strandcms.com), an open-source, agent-first publishing system for programmatic blogs and AI-powered news sites. Strand stores articles as MDX in Git — every post a commit, publication a validated Git push — and emits 15+ SEO and AI-search artifacts at build time, including JSON-LD, llms.txt, and a clean Markdown version of every page. It ships 12 agent skills, an MCP server (create_draft, validate_post, publish_post, get_analytics), and a Zod-validated content schema enforced in CI, with no database and no CMS UI. MIT-licensed, Node 20+.

The useful shape of publishing MCP tools is a lifecycle, not a single super-tool. The Model Context Protocol documentation describes discoverable tools with structured inputs and results. A content system can use that contract to expose small editorial operations: create the file, validate the file, check the cluster, then publish the approved state.

This is a support article for Best MCP Server Publishing Tools in 2026. It also connects to Claude Code's full blog pipeline, AI content agents without slop, and Introducing Strand.

Publishing MCP tools: the lifecycle

brief → create_draft → validate_post → batch QA → review → publish_post

Each arrow matters. The next tool should consume the actual result of the previous step rather than a model's memory of what happened.

1. create_draft

create_draft should accept a slug, frontmatter, and body—or a similarly explicit typed payload. It should write only to the permitted working area and return a durable identifier such as the path or slug.

A good draft tool rejects malformed input early. It can check that the slug matches the filename, that an author exists, and that required fields are present. It should not silently convert a missing source into a complete article.

The tool should also be idempotent or explicit about overwrites. “Create” should not unexpectedly destroy an existing article because the model retried a request.

2. validate_post

validate_post checks the exact on-disk file against the content schema. In a Strand workflow that includes title and description limits, ISO dates, author references, content metadata, FAQ entries, sources, and the first <Grounding /> component.

The key word is exact. Validate the file that will be committed, not an in-memory draft that might differ from the repository. Return actionable errors with a field or line where possible.

A successful schema check is necessary, not sufficient. It does not verify that a source supports a claim or that a comparison is fair.

3. Batch QA

A post can validate alone and still fail as part of a cluster. Batch QA checks the link graph, keyword placement, word band, money-page link, sources, and the requirement that the pillar links every support. It also catches a missing planned file.

This is why publish_post should not be called per article when the editorial unit is a cluster. The batch is the thing that needs to be complete.

4. Review

Review is where the editor reads for meaning. Compare each factual sentence with its source. Check that the article answers its primary question in the opening. Look for repeated paragraphs, generic AI language, and competitor descriptions that hide a genuine strength.

A useful review record includes the source note, diff, validation output, and the intended publication date. That is enough context to make a release decision without reconstructing the whole prompt history.

5. publish_post

A publish operation should be the narrowest and most protected tool. Its inputs should identify the intended post or batch, and the server or wrapper should re-check status, branch ancestry, required files, and validation before the side effect.

The MCP specification defines the interaction model; it does not prescribe your publication policy. Your wrapper must supply that policy. In a Git-native system, the final operation can be a fast-forward of a validated branch to main.

Tool schemas should express the policy

Avoid an input like:

{"action":"do_anything","payload":"..."}

Prefer explicit inputs such as:

{"slug":"example-post","status":"draft"}

or:

{"batch":3,"expectedSlugs":["pillar","support-a"]}

Schemas are not a full security model, but they make invalid states visible and help clients choose the correct tool.

Permissions and failure states

Separate credentials for draft and publish operations reduce blast radius. A read-only research client should not be able to push. A draft writer should not be able to bypass batch QA. GitHub rulesets can provide repository-level enforcement around updates and required checks.

Design failures as normal results: source unavailable, invalid frontmatter, missing article, stale branch, failed QA, or denied permission. The agent should report the exact blocker and stop.

Strand's concrete example

Strand's repository is the source for its documented MCP tool names and Git-native workflow. The useful pattern is not the brand-specific names; it is the sequence. A structured draft is created, the exact post is validated, the batch is checked, and publication is a separate action.

That sequence keeps the source visible and gives the editor several points at which to catch unsupported claims or accidental scope expansion.

Designing the result object

A tool result should help the next step decide what to do. For a draft, return the path, slug, and whether an existing file was changed. For validation, return pass or fail plus field-level errors. For batch QA, return every article and every failed check. For publication, return the target branch and commit or a clear failure.

Avoid a result that says only “success.” The agent needs enough detail to avoid repeating a completed write or claiming that a different file was validated. A useful result is part of the audit trail.

Content state is not tool state

A tool can report that it wrote a file while the article remains a draft. A validator can report that the schema passed while the sources are weak. A publication command can report a push while the site deployment is still processing. Keep these states distinct in both the interface and the run report.

This distinction prevents overclaiming. The editor can say “the batch branch passed validation and was pushed” without saying “every reader has seen the updated page” unless deployment has also been verified.

A minimal lifecycle example

Imagine a support article about Claude Code. The agent first receives a brief and source list. create_draft writes the MDX. validate_post checks the frontmatter and component order. Batch QA verifies the support links back to its pillar and includes a money-page link. The reviewer checks the Anthropic documentation against the claims. Only then does the batch-level publish operation run.

If the title is too long, the schema fails. If an API claim lacks a first-party URL, editorial review fails. If the pillar does not link the support, QA fails. Each failure is better than a polished but incomplete release.

What not to expose

Do not expose arbitrary shell execution, unrestricted database writes, credential retrieval, or a tool that combines research, drafting, and publication into one opaque action unless the surrounding environment has a compelling reason and strong controls. Most editorial workflows need less power than that.

Least privilege also improves usability. When a tool has one job, its description can be precise, its input schema can be small, and its error can point to a specific correction.

Version the contract

MCP specifications and vendor clients evolve. Keep the server's supported protocol version, tool descriptions, and input schemas visible to the project. When a tool changes behavior, test an existing article fixture before connecting it to the production workflow.

Versioning is not overkill for a publication. It lets the editor distinguish a content error from an integration change and gives the team a clear place to document compatibility.

Test with fixtures

Use a valid article, a missing-field article, a bad-link article, and an intentionally incomplete batch as fixtures. The expected result should be explicit for each one. A server that passes the valid fixture but also publishes the incomplete batch is not safe enough, regardless of how convenient the happy path feels.

Fixtures also make refactoring less risky. When the content schema or tool wrapper changes, rerun the same examples and inspect the result rather than relying on a manual click-through.

Why this matters

A publishing MCP is an interface between an agent and a release system. Good interfaces reduce ambiguity. They make the safe path discoverable, make bad inputs rejectable, and make the final side effect rare enough to inspect.

The best implementation is not the one with the cleverest tool name. It is the one that still refuses to publish when the article is incomplete.

Questions

What are publishing MCP tools?
They are MCP-exposed functions for bounded editorial actions, such as creating a draft, validating a post, or requesting a controlled publication.
Why separate create_draft and publish_post?
Separation keeps drafting reversible and lets validation, review, and permission checks happen before a production side effect.
Does validate_post prove an article is good?
It proves the checks it implements passed. Editorial judgment, source quality, fairness, and usefulness still require review.

Sources

  1. Tools - Model Context Protocol — Model Context Protocol
  2. Model Context Protocol Specification — Model Context Protocol
  3. Claude Code MCP — Anthropic
  4. Strand CMS — BowTiedSwan
  5. About rulesets — GitHub