From 3b47da2611f11c46e9c3a0fce24eae34b800da2f Mon Sep 17 00:00:00 2001 From: repo-pipeline Date: Wed, 3 Jun 2026 10:17:46 -0700 Subject: [PATCH] Add CLI MCP and skill surfaces --- .github/workflows/tests.yml | 2 + .mcp.json | 8 ++ README.md | 37 +++++++- creator_kit_cli.py | 100 +++++++++++++++++++++ creator_kit_mcp.py | 120 ++++++++++++++++++++++++++ skills/creator-kit/SKILL.md | 49 +++++++++++ skills/creator-kit/agents/openai.yaml | 7 ++ tests/test_agent_surfaces.py | 21 +++++ 8 files changed, 343 insertions(+), 1 deletion(-) create mode 100644 .mcp.json create mode 100755 creator_kit_cli.py create mode 100755 creator_kit_mcp.py create mode 100644 skills/creator-kit/SKILL.md create mode 100644 skills/creator-kit/agents/openai.yaml create mode 100644 tests/test_agent_surfaces.py diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 3d03c21..efd3adb 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -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 diff --git a/.mcp.json b/.mcp.json new file mode 100644 index 0000000..3bd5102 --- /dev/null +++ b/.mcp.json @@ -0,0 +1,8 @@ +{ + "mcpServers": { + "creator-kit": { + "command": "python", + "args": ["-m", "creator_kit_mcp"] + } + } +} diff --git a/README.md b/README.md index 7bd5eab..9c47593 100644 --- a/README.md +++ b/README.md @@ -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. @@ -8,7 +9,7 @@ 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 @@ -16,9 +17,41 @@ Creator Kit is a public-safe workspace for reusable creator tools: prompt librar - `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 @@ -26,6 +59,7 @@ Creator Kit is a public-safe workspace for reusable creator tools: prompt librar - AI-assisted content production rules - repeatable creative operations - lightweight studio process templates +- channel-aware content briefs and readiness checks ## Public Safety @@ -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 diff --git a/creator_kit_cli.py b/creator_kit_cli.py new file mode 100755 index 0000000..cf8ef5c --- /dev/null +++ b/creator_kit_cli.py @@ -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() diff --git a/creator_kit_mcp.py b/creator_kit_mcp.py new file mode 100755 index 0000000..7a75959 --- /dev/null +++ b/creator_kit_mcp.py @@ -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() diff --git a/skills/creator-kit/SKILL.md b/skills/creator-kit/SKILL.md new file mode 100644 index 0000000..81a37ee --- /dev/null +++ b/skills/creator-kit/SKILL.md @@ -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. diff --git a/skills/creator-kit/agents/openai.yaml b/skills/creator-kit/agents/openai.yaml new file mode 100644 index 0000000..0b3d367 --- /dev/null +++ b/skills/creator-kit/agents/openai.yaml @@ -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 diff --git a/tests/test_agent_surfaces.py b/tests/test_agent_surfaces.py new file mode 100644 index 0000000..3fd3cd8 --- /dev/null +++ b/tests/test_agent_surfaces.py @@ -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"] + )