Build a workflow over MCP
Read a workflow's graph, add nodes, connect them, attach renderers and transformers, and compose social posts from your AI client.
A project holds one or more workflows, and a workflow is a graph of nodes: content nodes, outputs from a renderer (a presentation, a document, a blog post, a social post), transformers, connected accounts, themes and triggers. It is the same graph you see on the flow canvas in the app.
The tools on this page are that canvas, addressable from your client. Each one
names the workflow it acts on by project id and workflow id, both of
which you get from save_project, create_workflow, or the project's URL.
Reading the graph
get_workflowreturns the shape of the graph: every node and every connection. Node content is left out, which keeps it cheap to call between steps. Start here when you did not build the workflow in this conversation.get_node_outputreturns one node's content: what a renderer produced, or a content node's resolved text. For a social post, passplatformto see that platform's version instead of the shared default. Anything too large to return in full comes back flagged, never quietly cut short.
Adding and connecting nodes
-
create_workflowadds a new, empty workflow to a project and returns its id, which is where you start when you build one from scratch. -
add_nodeplaces one node and returns its id. The kinds are:Kind Notes contentA content node. Pass title, andmarkdownto seed it with text.outputA renderer output. Pass renderer_id:slides,document,blogorsocial-post.transformerPicks and reorders sections from what feeds it. accountRefers to an account you connected in the app. Pass its connection_id.triggerFires publishing for the posts it reaches. cacheHolds a value between the step that produces it and the step that uses it. themeThe shared look outputs render with. Pass theme.You can also pass a
positionso the node lands somewhere sensible when you open the canvas. -
connect_nodesdraws a connection between two nodes. Papera works out what the connection means from the two ends: content to output attaches a source, post to account sends the post there, trigger to node makes the trigger fire it. A connection that is not allowed is refused with the reason, for example "that output already has a content source".
Shortcuts
These save round trips. They do nothing you could not do with add_node and
connect_nodes, and they return what the new node produced so you can check it
straight away.
attach_renderercreates an output over a content node or transformer and connects it in one call. This is how content becomes a presentation, a document, a blog post or a social post.attach_transformercreates a transformer over a source and wires it up. A transformer picks and reorders the sections it takes from upstream; with nosection_idsit passes everything through. Use one when an output should show part of a content node rather than all of it.target_accountssends one post to several accounts at once. Each account is handled on its own, so any that cannot take the post are reported with the reason while the rest still connect.edit_postsets a post's content.
Composing a social post
A social post has a shared default plus optional per-platform versions. A version overrides only the fields it sets and inherits the rest, so you write the post once and tailor only what needs tailoring.
edit_post takes:
default_blocks: the shared content, as an ordered list of content blocks.variants: overrides keyed by platform id (instagram,bluesky,telegram,linkedin), each setting any ofcaption,hashtagsormedia.
{
"default_blocks": [
{
"id": "b1",
"type": "paragraph",
"content": [{ "type": "text", "text": "Our Q3 numbers are in." }]
}
],
"variants": {
"bluesky": { "caption": "Q3 is in. Three charts, one takeaway.", "hashtags": ["q3"] },
"instagram": { "media": [{ "blockId": "b2", "src": "https://example.com/chart.png" }] }
}
}
Hashtags are written without the leading #. Media must be http(s) URLs, as
there is no upload path over MCP: upload images in the app, or point at a URL
that is already public.
Connected accounts
Connecting a social account always happens in the app, never over MCP. An
account node refers to a connection you already made there, so connect the
account first (see Connect a Bluesky account or
Connect a Telegram channel), then add a node for it
with its connection_id.
What comes next
A workflow with a post and accounts is ready to go out. See Publish and schedule, or follow Example: one post, every account for the whole sequence.