Letting an AI assistant publish to your social accounts, safely
Connecting an AI assistant to a drafting tool is unremarkable. Connecting one to an account with an audience is a different thing, and the difference is that publishing cannot be taken back.
We built an MCP server for exactly this, and most of the work was not in making it capable. It was in making the dangerous parts hard to reach by accident.
What MCP actually is
The Model Context Protocol is a standard for exposing tools to an AI assistant. A server advertises a list of tools with names, descriptions and typed inputs; the assistant reads that list and decides what to call. The user authorises the connection once, through OAuth, and can revoke it.
That is the whole idea, and it is a good one. It also means the tool list is a user interface, read by something that will act on it without asking.
Names are the first safety control
An assistant chooses a tool by reading its name and description. So a tool
called create_post is ambiguous in a way that matters: create it where? As a
draft? Live?
Ours are named for their effect on the audience:
cybe_create_draft_post— reaches nobodycybe_schedule_post— reaches an audience latercybe_publish_post_now— reaches an audience now
None of those can be confused for another by a model skimming a list. Naming them after the database operation, which is the natural instinct for an engineer, throws that away.
Publishing gets its own permission
Draft and schedule live under one OAuth scope. Publishing has its own.
The important consequence is not that publishing is "protected" — it is that a connection granted only drafting never sees the publish tool at all. It is not in the list the assistant reads. There is nothing to be tempted by, nothing to hallucinate the arguments for, and nothing to refuse.
A permission that hides a capability is stronger than one that guards it.
The dangerous tool refuses its first call
cybe_publish_post_now will not publish on the first attempt. Without an
explicit confirm: true, it returns a dry run: the exact accounts it would post
to, and the caption it would use.
This exists because of how these conversations actually go. Someone says "yes, go ahead" to a summary the assistant wrote, and the summary is not always the thing the tool is about to do. The dry run makes the tool's own account of itself the thing being approved.
It is also the difference between a mistake that costs a message and a mistake that costs a post on a company page.
Annotations help, but they are hints
MCP has destructiveHint, and we set it. A host may prompt the user when it
sees one. It may also not.
Anything that depends on a hint being honoured is not a control. Treat annotations as a courtesy to well-behaved clients, and put the real guarantees in scopes and in the tool's own behaviour.
Uploads need a checksum, which we learned the hard way
MCP carries JSON, so a file arrives base64-encoded. Base64 is not self-checking, and Node's decoder never complains: a payload altered in transit still decodes, to a different file.
We stored an 8,983-byte PDF for an 8,981-byte original. It uploaded cleanly,
listed cleanly and reported its size. The first sign of a problem was a human
opening it days later and finding no page tree and no %%EOF.
The upload tool now accepts a sha256 and refuses a mismatch before anything is
stored, and returns the digest of the stored bytes either way so an assistant
can verify its own upload instead of asking someone to look.
If you build an MCP tool that accepts a file, do this on day one.
The rule underneath all of it
Assume the assistant is capable, well-intentioned and occasionally wrong about what it was asked to do. Design so that being wrong is cheap.
Everything above follows from that.
Frequently asked questions
What is MCP?
The Model Context Protocol is an open standard that lets an AI assistant call external tools. A server exposes a set of tools, the assistant discovers them, and the user approves what the assistant may do.
Can an AI assistant post to social media on my behalf?
Yes, if you connect it to a service that exposes publishing as an MCP tool and you grant that permission. The safeguard is scoping: a connection can be granted drafting and scheduling without being granted the ability to publish.
What stops an AI assistant from publishing something by mistake?
Good design rather than good intentions. Publishing should require its own OAuth scope, so it is invisible to a token that was not granted it, and the tool should return a dry run on its first call so a person can confirm the accounts and the text before anything goes out.