Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Run structural tests
run: bash tests/structural.sh
Expand Down
8 changes: 8 additions & 0 deletions .mcp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"mcpServers": {
"creator-kit": {
"command": "python",
"args": ["-m", "creator_kit_mcp"]
}
}
}
37 changes: 36 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Creator Kit

**Open-source creator workflow kit for prompts, publishing systems, reusable assets, and AI-assisted content production**

Creator Kit is a public-safe workspace for reusable creator tools: prompt libraries, publishing workflow patterns, content-production checklists, agent-law guidance, and lightweight systems for turning creative work into repeatable output.
Expand All @@ -8,24 +9,57 @@ Creator Kit is a public-safe workspace for reusable creator tools: prompt librar
- **What it is:** a creator operations kit for reusable prompts, content workflows, publishing systems, and AI-assisted production patterns.
- **Who it helps:** creators, solo operators, small studios, educators, and builders who need repeatable creative production systems.
- **Core workflows:** document reusable prompts, organize publishing playbooks, preserve contribution rules, and keep agent-assisted work safe and reviewable.
- **Stack:** Markdown-first documentation and GitHub workflows.
- **Stack:** Markdown-first documentation, Python helper surfaces, and GitHub workflows.
- **Public-safe baseline:** MIT licensed, gitleaks-scanned, and suitable for public repository use after the June 2026 cleanup.

## Repo Map

- `README.md` - public overview and discovery surface.
- `llms.txt` - AI/agent navigation summary.
- `docs/agent-law/` - agent operating rules and contribution boundaries.
- `creator_kit_cli.py` - local CLI for briefs, content plans, and asset checklists.
- `creator_kit_mcp.py` - stdio MCP server for agent hosts.
- `skills/creator-kit/SKILL.md` - public agent skill.
- `GITHUB_GUARDIAN_AUDIT.md` - repository hygiene notes.
- `.github/workflows/` - lightweight repository smoke and agent-law checks.

## Quick Start

```bash
python -m creator_kit_cli brief
python -m creator_kit_cli plan --topic "AI-assisted creator workflow" --audience "solo creators" --channel newsletter
python -m creator_kit_cli checklist --asset-type "launch thread"
```

## Agent Surfaces

Creator Kit exposes three public agent surfaces:

- CLI: `python -m creator_kit_cli` for project briefs, content plans, and asset checklists.
- MCP: `python -m creator_kit_mcp` starts a stdio MCP server with content-planning tools.
- Skill: [`skills/creator-kit/SKILL.md`](skills/creator-kit/SKILL.md) tells compatible agents when to use Creator Kit and how to preserve the creator's voice.

Example MCP config:

```json
{
"mcpServers": {
"creator-kit": {
"command": "python",
"args": ["-m", "creator_kit_mcp"]
}
}
}
```

## Use Cases

- creator workflow documentation
- prompt and publishing system organization
- AI-assisted content production rules
- repeatable creative operations
- lightweight studio process templates
- channel-aware content briefs and readiness checks

## Public Safety

Expand All @@ -38,6 +72,7 @@ Do not commit API keys, private drafts, client material, unreleased account stra
```bash
gitleaks git . --no-banner --redact
gitleaks dir . --no-banner --redact
python -m pytest -q
```

## AI and Search Metadata
Expand Down
100 changes: 100 additions & 0 deletions creator_kit_cli.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
#!/usr/bin/env python3
"""Creator-kit command-line interface."""

from __future__ import annotations

import argparse
import json
from typing import Any


def project_brief() -> dict[str, Any]:
return {
"name": "Creator-kit",
"summary": "Open-source creator workflow kit for prompts, publishing systems, reusable assets, and AI-assisted content production.",
"surfaces": {
"cli": "python -m creator_kit_cli",
"mcp": "python -m creator_kit_mcp",
"skill": "skills/creator-kit/SKILL.md",
},
"workflows": [
"turn a raw idea into a publishable content brief",
"plan reusable creator assets and repurposing paths",
"check whether a draft has hook, audience, proof, and call-to-action clarity",
],
}


def content_plan(args: dict[str, Any]) -> dict[str, Any]:
topic = str(args.get("topic") or "untitled idea").strip()
audience = str(args.get("audience") or "target audience").strip()
channel = str(args.get("channel") or "general").strip()
return {
"topic": topic,
"audience": audience,
"channel": channel,
"brief": f"Create a {channel} piece about {topic} for {audience}.",
"outline": [
"hook: name the pain, opportunity, or surprising contrast",
"context: explain why this matters now",
"body: give the useful steps, evidence, or example",
"close: ask for one concrete response or next action",
],
"repurposing": [
"short post",
"long-form outline",
"newsletter section",
"talking points for video",
],
}


def asset_checklist(args: dict[str, Any]) -> dict[str, Any]:
asset_type = str(args.get("asset_type") or "content asset").strip()
return {
"asset_type": asset_type,
"checks": [
"clear audience",
"specific promise",
"one reusable source of truth",
"format-specific constraints",
"proof, example, or artifact",
"repurposing notes",
"publishing owner and next action",
],
}


def _print(payload: dict[str, Any]) -> None:
print(json.dumps(payload, indent=2, sort_keys=True))


def main() -> None:
parser = argparse.ArgumentParser(
description="Creator-kit CLI for content workflow planning."
)
subparsers = parser.add_subparsers(dest="command", required=True)

subparsers.add_parser("brief", help="Print the Creator-kit project brief.")

plan = subparsers.add_parser("plan", help="Create a content plan.")
plan.add_argument("--topic", required=True)
plan.add_argument("--audience", default="target audience")
plan.add_argument("--channel", default="general")

checklist = subparsers.add_parser(
"checklist", help="Create an asset readiness checklist."
)
checklist.add_argument("--asset-type", default="content asset")

args = parser.parse_args()
if args.command == "brief":
_print(project_brief())
elif args.command == "plan":
_print(content_plan(vars(args)))
elif args.command == "checklist":
_print(asset_checklist({"asset_type": args.asset_type}))


if __name__ == "__main__":
main()
120 changes: 120 additions & 0 deletions creator_kit_mcp.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
#!/usr/bin/env python3
"""Creator-kit stdio MCP server."""

from __future__ import annotations

import json
import sys
from typing import Any

from creator_kit_cli import asset_checklist, content_plan, project_brief

PROTOCOL_VERSION = "2024-11-05"

TOOLS = {
"creator_kit_project_brief": {
"description": "Return Creator-kit identity, surfaces, and workflow summary.",
"handler": lambda _args: project_brief(),
"inputSchema": {"type": "object", "properties": {}},
},
"create_content_plan": {
"description": "Create a reusable content plan from topic, audience, and channel.",
"handler": content_plan,
"inputSchema": {
"type": "object",
"properties": {
"topic": {"type": "string"},
"audience": {"type": "string"},
"channel": {"type": "string"},
},
"required": ["topic"],
},
},
"asset_readiness_checklist": {
"description": "Return a creator asset readiness checklist.",
"handler": asset_checklist,
"inputSchema": {
"type": "object",
"properties": {"asset_type": {"type": "string"}},
},
},
}


def handle_tool_call(
name: str, arguments: dict[str, Any] | None = None
) -> dict[str, Any]:
if name not in TOOLS:
raise ValueError(f"Unknown tool: {name}")
return TOOLS[name]["handler"](arguments or {})


def _tool_list() -> list[dict[str, Any]]:
return [
{
"name": name,
"description": spec["description"],
"inputSchema": spec["inputSchema"],
}
for name, spec in TOOLS.items()
]


def _response(message_id: Any, result: dict[str, Any]) -> dict[str, Any]:
return {"jsonrpc": "2.0", "id": message_id, "result": result}


def _error(message_id: Any, code: int, message: str) -> dict[str, Any]:
return {
"jsonrpc": "2.0",
"id": message_id,
"error": {"code": code, "message": message},
}


def handle_message(message: dict[str, Any]) -> dict[str, Any] | None:
method = message.get("method")
message_id = message.get("id")
params = message.get("params") or {}
if message_id is None:
return None
if method == "initialize":
return _response(
message_id,
{
"protocolVersion": PROTOCOL_VERSION,
"capabilities": {"tools": {}},
"serverInfo": {"name": "creator-kit", "version": "0.1.0"},
},
)
if method == "tools/list":
return _response(message_id, {"tools": _tool_list()})
if method == "tools/call":
try:
result = handle_tool_call(
params.get("name", ""), params.get("arguments") or {}
)
return _response(
message_id,
{"content": [{"type": "text", "text": json.dumps(result, indent=2)}]},
)
except ValueError as exc:
return _error(message_id, -32602, str(exc))
return _error(message_id, -32601, f"Unsupported method: {method}")


def main() -> None:
for line in sys.stdin:
if not line.strip():
continue
try:
reply = handle_message(json.loads(line))
except json.JSONDecodeError as exc:
reply = _error(None, -32700, f"Invalid JSON: {exc}")
if reply is not None:
sys.stdout.write(json.dumps(reply) + "\n")
sys.stdout.flush()


if __name__ == "__main__":
main()
49 changes: 49 additions & 0 deletions skills/creator-kit/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
---
name: creator-kit
description: Use Creator-kit for creator workflows, content briefs, publishing systems, reusable asset planning, prompt kits, and AI-assisted content production. Trigger when an agent needs to turn an idea into a channel-aware plan or check whether a draft is ready to publish.
---

# Creator-kit

Use this skill when a task involves creator systems, content planning, reusable prompt/assets, publishing workflows, or draft readiness.

## Start Here

- Read `../../README.md` for the current public surface.
- Use the CLI for local planning: `python -m creator_kit_cli`.
- Use the MCP server when an agent host should call creator workflow tools directly: `python -m creator_kit_mcp`.

## Workflow

1. Identify the topic, audience, and channel before writing.
2. Produce a short brief first: hook, context, useful body, and close.
3. Design every asset with reuse in mind: source of truth, derivatives, owner, and next action.
4. Keep generated copy ready to edit, not over-polished into a generic voice.
5. If publishing advice depends on current platform rules or trends, verify before claiming specifics.

## CLI Examples

```bash
python -m creator_kit_cli brief
python -m creator_kit_cli plan --topic "AI-assisted creator workflow" --audience "solo creators" --channel newsletter
python -m creator_kit_cli checklist --asset-type "launch thread"
```

## MCP Setup

```json
{
"mcpServers": {
"creator-kit": {
"command": "python",
"args": ["-m", "creator_kit_mcp"]
}
}
}
```

## Guardrails

- Do not invent platform policy, pricing, or performance claims from memory.
- Preserve the creator's voice; do not flatten everything into generic marketing copy.
- Separate draft text from publishing strategy when the user needs both.
7 changes: 7 additions & 0 deletions skills/creator-kit/agents/openai.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
interface:
display_name: "Creator-kit"
short_description: "Plan creator content and reusable assets"
default_prompt: "Use $creator-kit to turn this idea into a channel-aware content plan."

policy:
allow_implicit_invocation: true
21 changes: 21 additions & 0 deletions tests/test_agent_surfaces.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from creator_kit_mcp import handle_message, handle_tool_call


def test_mcp_creates_content_plan():
result = handle_tool_call(
"create_content_plan",
{"topic": "AI workflow", "audience": "solo creators", "channel": "newsletter"},
)

assert result["topic"] == "AI workflow"
assert "outline" in result


def test_mcp_lists_tools():
response = handle_message({"jsonrpc": "2.0", "id": 1, "method": "tools/list"})

assert response is not None
assert any(
tool["name"] == "asset_readiness_checklist"
for tool in response["result"]["tools"]
)
Loading