CtrlK
BlogDocsLog inGet started
Tessl Logo

content-publisher

Automates drafting and publishing articles to Substack and Medium with Apify and Notion integration

Install with Tessl CLI

npx tessl i github:oyi77/1ai-skills --skill content-publisher
What are skills?

Overall
score

18%

Does it follow best practices?

Validation for skill structure

Validation failed for this skill
This skill has errors that need to be fixed before it can move to Implementation and Activation review.
SKILL.md
Review
Evals

Content Publisher Agent

Automates drafting and publishing articles to Substack and Medium with workflow automation.

Required Tools

MCP Servers

Apify MCP (Publishing Automation)

{
  "mcpServers": {
    "apify": {
      "command": "npx",
      "args": ["-y", "@apify/mcp-server"],
      "env": { "APIFY_API_TOKEN": "${APIFY_API_TOKEN}" }
    },
    "notion": {
      "command": "npx",
      "args": ["-y", "@makenotion/mcp-server"],
      "env": { "NOTION_API_KEY": "${NOTION_API_KEY}" }
    },
    "slack": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-slack"],
      "env": { "SLACK_BOT_TOKEN": "${SLACK_BOT_TOKEN}" }
    }
  }
}

Tool Permissions

ToolCapabilities
Bash(apify:*)Execute browser automation for publishing
MCP(apify:*)Run web scraping/automation actors
MCP(notion:*)Store editorial calendar, track drafts
MCP(slack:*)Send approval notifications

Authentication

Setup

  1. Apify Token

    export APIFY_API_TOKEN="your-token"
  2. Notion Integration

    • Create integration at https://www.notion.so/my-integrations
    • Share database with integration
  3. Slack (optional)

    export SLACK_BOT_TOKEN="xoxb-your-token"

Capabilities

  • Drafting: Turn ideas into structured Markdown drafts
  • Publishing: Navigate to platform editors and publish
  • Cross-Posting: Sync content between platforms
  • Scheduling: Schedule posts for future publication
  • Editorial Calendar: Track in Notion

Pseudo Code

Example 1: Draft Article

// 1. Analyze request
const topic = "The impact of Agentic AI on coding";
const audience = "developers";
const tone = "professional";

// 2. Research if needed
const context = await apify.actor("apify/firecrawl-scraper", {
  urls: [`https://news.ycombinator.com/?q=${topic}`]
});

// 3. Generate content
const draft = await generateArticle({ topic, audience, tone, context });

// 4. Save to drafts folder
const filename = `memory/drafts/${dateSlug(topic)}.md`;
await fs.write(filename, draft);

// 5. Log to Notion editorial calendar
await notion.createPage("Editorial Calendar", {
  title: draft.title,
  status: "Draft",
  scheduledDate: null,
  platform: "both"
});

Example 2: Publish to Platform

// 1. Read draft
const content = await fs.read("memory/drafts/agentic-ai.md");

// 2. Navigate to platform
await browser.goto("https://medium.com/new-post");

// 3. Fill content
await browser.fill(".title-input", content.title);
await browser.fill(".body-editor", content.body);

// 4. Add tags
for (const tag of content.tags) {
  await browser.click(".tag-input");
  await browser.type(tag);
}

// 5. Publish or save draft
if (mode === "live") {
  await browser.click(".publish-button");
  await slack.notify("#content", `Published: ${content.title}`);
} else {
  await browser.click(".save-draft");
}

Example 3: Cross-Post to Both Platforms

// 1. Read content
const content = await fs.read(draftPath);

// 2. Convert for each platform
const mediumContent = convertToMedium(content);
const substackContent = convertToSubstack(content);

// 3. Publish to Medium
await publishToMedium(mediumContent);

// 4. Publish to Substack
await publishToSubstack(substackContent);

// 5. Update Notion
await notion.updatePage(draftId, { status: "Published" });

CLI Reference

CommandDescription
draft "topic"Generate article draft
publish <file> <platform>Publish to platform
publish <file> <platform> livePublish live
schedule <file> <platform> <datetime>Schedule post

Error Handling

Error CodeMeaningFix
AUTH_001Not logged inCheck credentials, re-login
PUBLISH_001Platform changed UIUpdate selectors
RATE_001Rate limitedWait and retry
VALIDATE_001Content validation failedCheck format

Common Patterns

Pattern: Dry-Run Publishing

async function publishWithDryRun(content, platform, dryRun = true) {
  // Validate content
  if (!content.title || !content.body) {
    throw new Error("Missing required fields");
  }

  // Preview
  console.log("=== PREVIEW ===");
  console.log(`Title: ${content.title}`);
  console.log(`Platform: ${platform}`);
  
  if (dryRun) {
    console.log("DRY RUN - No actual publishing");
    return { status: "preview" };
  }

  // Actually publish
  return await platform.publish(content);
}

Skill v2.0 - Content Publisher with MCP

Repository
github.com/oyi77/1ai-skills
Last updated
Created

Is this your skill?

If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.