Content Factory CrewAI
What it does
A researcher gathers current facts, numbers, and sources on the topic. A writer produces a draft with a clear point of view, using only what the research supports. An editor cuts filler, verifies each claim against the gathered sources, and tightens the structure. A publisher files the finished piece in Notion with the source list attached, ready for human review and posting. A classic sequential crew where the editor's standards, not a loop, carry the quality.
The cast Β· 4 agents
Edit hard: cut filler and hedging, check every claim against the research sources, fix structure so the strongest material leads. Flag any claim you could not verify rather than deleting it silently.
Write the piece for the stated audience with a clear point of view. Every factual claim must trace to the research. If the research is thin somewhere, narrow the piece rather than padding it.
File the edited piece in Notion with the title, the body, and the source list at the bottom. Do not post it anywhere public.
Gather current facts, numbers, and quotable sources on the topic. Prefer primary sources. Return each finding with its source. Note where sources disagree.
Flow
Interface
Depends on Β· 2 MCP servers
# Generated by @socketcat/compiler for target: langgraph
# blueprint: com.socketcat/content-factory v1.0.0 schema: socketcat.dev/blueprint/v0
# This code is yours. Edit it freely. The socketcat_runtime helper is optional and can be vendored.
from typing import TypedDict
from langgraph.graph import StateGraph, START, END
import socketcat_runtime as _rt
class State(TypedDict, total=False):
topic: object
piece: object
research: object
draft: object
edited: object
def node_AgentInvoke_0(state):
return _rt.run_agent("researcher", state, {"topic":"topic"}, "research")
def node_AgentInvoke_1(state):
return _rt.run_agent("writer", state, {"topic":"topic","research":"research"}, "draft")
def node_AgentInvoke_2(state):
return _rt.run_agent("editor", state, {"draft":"draft","research":"research"}, "edited")
def node_AgentInvoke_3(state):
return _rt.run_agent("publisher", state, {"edited":"edited"}, "piece")
def build():
b = StateGraph(State)
b.add_node("AgentInvoke_0", node_AgentInvoke_0)
b.add_node("AgentInvoke_1", node_AgentInvoke_1)
b.add_node("AgentInvoke_2", node_AgentInvoke_2)
b.add_node("AgentInvoke_3", node_AgentInvoke_3)
b.add_edge(START, "AgentInvoke_0")
b.add_edge("AgentInvoke_0", "AgentInvoke_1")
b.add_edge("AgentInvoke_1", "AgentInvoke_2")
b.add_edge("AgentInvoke_2", "AgentInvoke_3")
b.add_edge("AgentInvoke_3", END)
return b.compile()
INPUTS = ["topic"]
OUTPUTS = ["piece"]
if __name__ == "__main__":
_rt.main(build, INPUTS, OUTPUTS)
βΈblueprint.json (the portable format)
{
"id": "com.socketcat/content-factory",
"flow": {
"type": "sequence",
"blocks": [
{
"in": {
"topic": "topic"
},
"out": "research",
"use": "researcher",
"type": "agent"
},
{
"in": {
"topic": "topic",
"research": "research"
},
"out": "draft",
"use": "writer",
"type": "agent"
},
{
"in": {
"draft": "draft",
"research": "research"
},
"out": "edited",
"use": "editor",
"type": "agent"
},
{
"in": {
"edited": "edited"
},
"out": "piece",
"use": "publisher",
"type": "agent"
}
]
},
"tags": [
"marketing",
"content",
"sequential",
"editorial"
],
"title": "Content Factory",
"agents": {
"editor": {
"model": {
"hint": "reasoning"
},
"title": "Editor",
"instructions": "Edit hard: cut filler and hedging, check every claim against the research sources, fix structure so the strongest material leads. Flag any claim you could not verify rather than deleting it silently."
},
"writer": {
"model": {
"hint": "reasoning"
},
"title": "Writer",
"instructions": "Write the piece for the stated audience with a clear point of view. Every factual claim must trace to the research. If the research is thin somewhere, narrow the piece rather than padding it."
},
"publisher": {
"model": {
"hint": "fast"
},
"title": "Publisher",
"tools": [
"notes.create_page"
],
"instructions": "File the edited piece in Notion with the title, the body, and the source list at the bottom. Do not post it anywhere public."
},
"researcher": {
"model": {
"hint": "fast"
},
"title": "Researcher",
"tools": [
"search.web"
],
"instructions": "Gather current facts, numbers, and quotable sources on the topic. Prefer primary sources. Return each finding with its source. Note where sources disagree."
}
},
"estate": {
"draft": {
"type": "object",
"description": "The writer's draft."
},
"edited": {
"type": "object",
"description": "The editor's final cut with claim checks."
},
"research": {
"type": "object",
"description": "Facts, numbers, and sources gathered on the topic."
}
},
"$schema": "socketcat.dev/blueprint/v0",
"authors": [
{
"url": "https://socketcat.com",
"name": "SocketCat"
}
],
"license": "MIT",
"servers": [
{
"ref": "io.github.brave/brave-search-mcp",
"alias": "search"
},
{
"ref": "com.notion/mcp",
"alias": "notes"
}
],
"summary": "Researches a topic, writes a grounded draft, edits it against a quality bar, and files the finished piece in Notion.",
"targets": [
"crewai",
"langgraph",
"*"
],
"version": "1.0.0",
"interface": {
"inputs": {
"topic": {
"type": "string",
"description": "The topic, the audience, and the angle if you have one."
}
},
"outputs": {
"piece": {
"type": "string",
"description": "The finished piece as filed in Notion, with sources."
}
}
},
"extensions": {
"com.crewai": {
"process": "sequential"
}
},
"description": "A researcher gathers current facts, numbers, and sources on the topic. A writer produces a draft with a clear point of view, using only what the research supports. An editor cuts filler, verifies each claim against the gathered sources, and tightens the structure. A publisher files the finished piece in Notion with the source list attached, ready for human review and posting. A classic sequential crew where the editor's standards, not a loop, carry the quality."
}