From matty-tiger-skills
Finalizes a published content piece by updating its Asana task on the MKTG Content Calendar. Sets the status to "Published!", adds the published URL, completes the "Add final published link" subtask, and marks the task done. Optionally announces the publication in #content-flywheel on Slack. Trigger when the user says they've published a blog post, LinkedIn article, or other content and want to update the Asana card — or when they mention "finalize", "mark as published", "close out the content task", "update the card", "it's live", or similar. Also trigger if the user runs /finalize-content.
How this skill is triggered — by the user, by Claude, or both
Slash command
/matty-tiger-skills:finalize-contentThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
This skill handles the "last mile" after a piece of content (blog post, LinkedIn article, video, etc.) goes live. It updates the Asana task on the MKTG Content Calendar so the board accurately reflects what's been published, and optionally announces it to the team in Slack.
This skill handles the "last mile" after a piece of content (blog post, LinkedIn article, video, etc.) goes live. It updates the Asana task on the MKTG Content Calendar so the board accurately reflects what's been published, and optionally announces it to the team in Slack.
Read 00 - System/Claude Context.md from the Obsidian vault using obsidian_get_file_contents.
This is the memory layer — team, key people, shorthand, active projects. Internalize it
silently (don't summarize it back).
Read config.json from the plugin root to get:
asana_project_id — the MKTG Content Calendar project (used to scope task searches)slack_channels — list of known Slack channels (includes #content-flywheel)These are specific to the MKTG Content Calendar and don't change:
1213144715555970 (enum)12131447155559751213474863169563 (text)C08R4GCABHUThese are used during task discovery to narrow results:
1213144715555977 (enum)
1213144715555978 (covers blog posts and LinkedIn articles)12131447155559801213144715555979121314471555598212131447155559741213144715555973You need two things: which task and the published URL. The Slack announcement is optional. Here's how to gather them efficiently.
The user might identify the task in several ways — and some are more specific than others. Handle each case:
User gave you an Asana URL or task GID: Skip straight to Step 2 (fetch the task directly).
User named a specific post: Search for it — see Step 1 below.
User didn't specify a task (just said "finalize" or "mark something as published"):
Proactively show them their finalize-ready tasks. Use search_tasks_preview with:
projects_any: the asana_project_id from configassignee_any: "me"completed: falseThis gives the user a list of their open content tasks to pick from. The Asana MCP's search_tasks_preview renders a nice preview card — after calling it, just ask the user which one they want to finalize. Don't try to summarize or list the tasks yourself; the preview card handles that.
The live link where the content was published (e.g. https://www.tigerdata.com/blog/some-post or a LinkedIn article URL). If the user hasn't provided it, ask.
Ask whether they'd like to post an announcement to #content-flywheel. Default to offering it (it's the team norm), but always confirm before sending.
Use the asana_project_id from config.json to scope searches to the content calendar.
If the user named a specific post: use search_tasks_preview with:
projects_any: the asana_project_id from configtext: keywords from what the user saidcompleted: falseIf multiple results match and it's not obvious which one, the preview card will show the user the options — ask them to pick. If nothing matches, try search_objects (resource_type: task) with different keywords as a fallback.
If the user didn't specify: show them the proactive list as described above, then wait for them to pick.
Once you've identified the right task, use get_task with include_subtasks: true and include_comments: false to get:
permalink_url (to include in the summary)Use update_tasks to do all of the following in a single call:
{
"tasks": [{
"task": "<task_gid>",
"completed": true,
"custom_fields": {
"1213144715555970": "1213144715555975",
"1213474863169563": "<the_published_url>"
}
}]
}
This single call sets the status to "Published!", fills in the Published URL, and marks the task complete.
Look through the subtasks from Step 2 for one named "Add final published link" — match case-insensitively and be a little fuzzy (it might be worded slightly differently across tasks). If you find it and it's incomplete, mark it complete:
{
"tasks": [{
"task": "<subtask_gid>",
"completed": true
}]
}
If this subtask doesn't exist or is already completed, skip silently. It's not worth mentioning to the user.
If the user wants a Slack announcement, send a message to #content-flywheel (C08R4GCABHU).
Keep it short and not annoyingly corporate. Include the content title and the published URL. Something like:
:rocket: New content published: [Task Name] — <published_url>
Vary the emoji and phrasing so it doesn't feel like a bot every time. If you know the content type from the task's custom fields, work it in naturally (e.g. "New blog post published" vs "New LinkedIn article published" vs "New video published"). One to two lines max.
Use slack_send_message (not slack_send_message_draft) since this is a simple factual announcement, not something that needs user review before sending. That said — you already confirmed the user wants to send it in the earlier step, so this is expected.
update_tasks fails: tell the user what went wrong and stop. Don't send the Slack message if the Asana update didn't go through.After everything's done, give the user a quick recap:
Keep it concise — a few lines, not a dissertation.
npx claudepluginhub mattstratton/skills-poc --plugin matty-tiger-skillsGenerates client-facing project heartbeat/status update messages for Kanopi projects by pulling activity from Teamwork and Fathom, then drafting in a consistent voice and format.
Provides scannable structures, honest framing, and warm recognition for team status updates, progress reports, and stakeholder communications.